git-mikado/src/commands/status.js

130 lines
3.5 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 iconFor = ( branch, branches ) => {
if(branch.done ) return "✅";
for( const dep of branch.dependencies ) {
if( !branches[dep].done ) return "⛔";
}
return "🙋";
}
module.exports = async (yargs) => {
const config = (await Git().listConfig("local")).all;
let tree = Object.entries(config).reduce(
(accum, [key, value]) => u.updateIn(key, value, accum),
{}
);
const branches = {};
const normalizeArray = (value) =>
Array.isArray(value) ? value : [value].filter((x) => x);
const initBranch = (config) =>
defaults(
{
upstream: [],
dependencies: [],
},
config
);
const current = (await Git().raw("branch", "--show-current")).replace(
"\n",
""
);
for (const branch in tree.branch) {
const entry = tree.branch[branch];
if (!("mikado-upstream" in entry)) continue;
branches[branch] = initBranch({
name: branch,
upstream: normalizeArray(entry["mikado-upstream"]),
base: entry["mikado-base"],
done: entry["mikado-done"],
});
}
for (const branch of Object.values(branches)) {
for (const ups of branch["upstream"]) {
if (!branches[ups])
branches[ups] = initBranch({
name: ups,
upstream: [],
dependencies: [],
});
branches[ups].dependencies.push(branch.name);
}
}
if (branches[current]) branches[current].current = true;
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);
};
console.log("\n=== 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(" "));
}
}
};