140 lines
3.5 KiB
JavaScript
140 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 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 printNeedsMerging());
|
|
|
|
accumSomething(await printNeedsRebasing());
|
|
|
|
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();
|
|
};
|