git-mikado/src/commands/status.js

154 lines
3.9 KiB
JavaScript

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 ?? "<none>")}`);
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();
};