const Git = require("simple-git"); const inquirer = require("inquirer"); const report = require("yurnalist"); const _ = require("lodash"); const { defaults } = require("lodash/fp"); const u = require("updeep"); const columnify = require("columnify"); const chalk = require("chalk"); const myGit = require('../branches'); const log = require('../log'); const iconFor = ( branch, branches ) => { if(branch.done ) return "✅"; for( const dep of branch.dependencies ) { if( !branches[dep].done ) return "⛔"; } return "🙋"; } const decorateCurrent = async branch => { if( branch !== await myGit.currentBranch() ) return branch; return chalk.underline.bold(branch); } async function printNeedsRebasing() { const needsRebasing = await myGit.needsRebasing(); if( !needsRebasing.length ) return false; log.subtitle(':arrow_heading_up: needs rebasing'); const b = await Promise.all( needsRebasing.map( decorateCurrent ) ); log.info( "\t", b.join(', ') ); return true; } async function printNeedsMerging() { const needsMerging = await myGit.needsMerging(); if(!needsMerging.length) return false; log.subtitle(':thumbsup: ready to be merged'); log.info( "\t", needsMerging.map( x => x.join('->') ).join(', ') ); return true; } async function printActionables() { log.title(":point_right: What's next?"); let something = false; const accumSomething = (value) => something ||= value; accumSomething( await printNeedsRebasing() ); accumSomething( await printNeedsMerging() ); const canBeDeleted = await myGit.canBeDeleted(); if( canBeDeleted.length ) { something = true; log.subtitle(':recycle: branches that can be deleted'); log.info( "\t", canBeDeleted.join(', ') ); } const canBeWorkedOn = await myGit.canBeWorkedOn(); if( canBeWorkedOn.length ) { something = true; log.subtitle(':hammer: ready to be worked on'); const b = await Promise.all( canBeWorkedOn.map( decorateCurrent ) ); log.info( "\t", b.join(', ') ); } if(!something) { log.info("nothing? :shrug:"); } } module.exports = async () => { const branches = await myGit.branches(); const depColor = (current) => async (dep) => { let color = branches[dep].done ? chalk.green : chalk.red; let contains = await Git().raw("branch", "--contains", dep); contains = contains .split("\n") .map((x) => x.trim().replace("* ", "")); if (contains.includes(current)) color = color.underline; return color(dep); }; const upstreamColor = (current) => async (up) => { let color = branches[up].done ? chalk.green : chalk.red; let contains = await Git().raw("branch", "--contains", current); contains = contains .split("\n") .map((x) => x.trim().replace("* ", "")); if (contains.includes(up)) color = color.underline; return color(up); }; log.title(":chopsticks: Mikado status\n"); const sorted = _.sortBy(Object.values(branches), ["current"]); for (const branch of sorted) { console.log( iconFor(branch,branches), chalk.blue(branch.name), branch.current ? "👷" : ' ' ); console.log(`\tbase: ${chalk.magenta(branch.base ?? "")}`); if (branch.upstream.length) { const ups = await Promise.all( branch.upstream.map(upstreamColor(branch.name)) ); console.log("\tupstream:", ups.join(" ")); } if (branch.dependencies.length) { const deps = await Promise.all( branch.dependencies.map(depColor(branch.name)) ); console.log("\tdependencies:", deps.join(" ")); } } await printActionables(); };