Merge branch 'gt9-no-done-no-clean'
This commit is contained in:
commit
5fc32f831a
@ -3,7 +3,7 @@ const u = require("updeep");
|
|||||||
const _ = require("lodash");
|
const _ = require("lodash");
|
||||||
const fp = require("lodash/fp");
|
const fp = require("lodash/fp");
|
||||||
|
|
||||||
const log = require('./log');
|
const log = require("./log");
|
||||||
|
|
||||||
const normalizeArray = (value) =>
|
const normalizeArray = (value) =>
|
||||||
Array.isArray(value) ? value : [value].filter((x) => x);
|
Array.isArray(value) ? value : [value].filter((x) => x);
|
||||||
@ -16,12 +16,14 @@ const initBranch = (config = {}) => ({
|
|||||||
|
|
||||||
const git = Git();
|
const git = Git();
|
||||||
|
|
||||||
const currentBranch = _.once(() =>git
|
const currentBranch = _.once(() =>
|
||||||
.raw("branch", "--show-current")
|
git.raw("branch", "--show-current").then((r) => r.replace("\n", ""))
|
||||||
.then((r) => r.replace("\n", "")));
|
);
|
||||||
|
|
||||||
|
const isClean = () => git.status().then(({ files }) => !files.length);
|
||||||
|
|
||||||
const branches = _.once(async () => {
|
const branches = _.once(async () => {
|
||||||
const config = await git.listConfig("local").then(fp.get('all'));
|
const config = await git.listConfig("local").then(fp.get("all"));
|
||||||
|
|
||||||
let tree = Object.entries(config).reduce(
|
let tree = Object.entries(config).reduce(
|
||||||
(accum, [key, value]) => u.updateIn(key, value, accum),
|
(accum, [key, value]) => u.updateIn(key, value, accum),
|
||||||
@ -58,9 +60,12 @@ const branches = _.once(async () => {
|
|||||||
|
|
||||||
// include the merged info
|
// include the merged info
|
||||||
for (const branch of Object.values(branches)) {
|
for (const branch of Object.values(branches)) {
|
||||||
branch.contains = _.compact(await git.raw( 'branch', '--merged', branch.name )
|
branch.contains = _.compact(
|
||||||
.then( r => r.replace( /[ *]/g, '' ) )
|
await git
|
||||||
.then( r => r.split("\n") ))
|
.raw("branch", "--merged", branch.name)
|
||||||
|
.then((r) => r.replace(/[ *]/g, ""))
|
||||||
|
.then((r) => r.split("\n"))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const current = await currentBranch();
|
const current = await currentBranch();
|
||||||
@ -73,43 +78,41 @@ const branches = _.once(async () => {
|
|||||||
async function canBeDeleted() {
|
async function canBeDeleted() {
|
||||||
const allBranches = await branches();
|
const allBranches = await branches();
|
||||||
|
|
||||||
return Object.values(allBranches).filter(
|
return Object.values(allBranches)
|
||||||
fp.get('done')
|
.filter(fp.get("done"))
|
||||||
).filter( ({name,upstream})=>
|
.filter(({ name, upstream }) =>
|
||||||
upstream.every( u => allBranches[u].contains.includes(name) )
|
upstream.every((u) => allBranches[u].contains.includes(name))
|
||||||
).map(fp.get('name'));
|
)
|
||||||
|
.map(fp.get("name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function canBeWorkedOn() {
|
async function canBeWorkedOn() {
|
||||||
const allBranches = await branches();
|
const allBranches = await branches();
|
||||||
|
|
||||||
return Object.values(allBranches).filter(
|
return Object.values(allBranches)
|
||||||
({done}) => !done
|
.filter(({ done }) => !done)
|
||||||
).filter( ({name,dependencies})=>
|
.filter(({ name, dependencies }) =>
|
||||||
dependencies.every( u => allBranches[u].done )
|
dependencies.every((u) => allBranches[u].done)
|
||||||
).map(fp.get('name'));
|
)
|
||||||
|
.map(fp.get("name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function needsRebasing() {
|
async function needsRebasing() {
|
||||||
const allBranches = await branches();
|
const allBranches = await branches();
|
||||||
|
|
||||||
return Object.values(allBranches).filter(
|
return Object.values(allBranches)
|
||||||
fp.get('base')
|
.filter(fp.get("base"))
|
||||||
).filter( ({base,name})=>
|
.filter(({ base, name }) => !allBranches[name].contains.includes(base))
|
||||||
!allBranches[name].contains.includes(base)
|
.map(fp.get("name"));
|
||||||
).map(fp.get('name'));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function needsMerging() {
|
async function needsMerging() {
|
||||||
const allBranches = await branches();
|
const allBranches = await branches();
|
||||||
|
|
||||||
return Object.values(allBranches).filter(
|
return Object.values(allBranches)
|
||||||
fp.get('done')
|
.filter(fp.get("done"))
|
||||||
).flatMap( ({upstream,name})=> upstream.map( u => [ name, u ] ) )
|
.flatMap(({ upstream, name }) => upstream.map((u) => [name, u]))
|
||||||
.filter( ([name,up]) => !allBranches[up].contains.includes(name) )
|
.filter(([name, up]) => !allBranches[up].contains.includes(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -119,4 +122,5 @@ module.exports = {
|
|||||||
canBeWorkedOn,
|
canBeWorkedOn,
|
||||||
needsRebasing,
|
needsRebasing,
|
||||||
needsMerging,
|
needsMerging,
|
||||||
|
isClean,
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
const Git = require('simple-git');
|
const Git = require("simple-git");
|
||||||
const inquirer = require('inquirer');
|
const inquirer = require("inquirer");
|
||||||
const report = require('yurnalist');
|
const report = require("yurnalist");
|
||||||
const _ = require('lodash');
|
const _ = require("lodash");
|
||||||
const { currentBranch } = require( '../utils');
|
|
||||||
|
const myGit = require("../branches");
|
||||||
|
const log = require("../log");
|
||||||
|
|
||||||
module.exports = async (yargs) => {
|
module.exports = async (yargs) => {
|
||||||
|
if (!(await myGit.isClean())) {
|
||||||
|
log.error("workspace not clean, aborting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const current = await currentBranch();
|
const current = await myGit.currentBranch();
|
||||||
|
|
||||||
console.log(`marking branch '${current}' as done`);
|
log.success(`W00t! marking branch '${current}' as done`);
|
||||||
|
|
||||||
await Git().addConfig(`branch.${current}.mikado-done`, true);
|
await Git().addConfig(`branch.${current}.mikado-done`, true);
|
||||||
|
};
|
||||||
}
|
|
||||||
|
@ -7,8 +7,8 @@ const u = require("updeep");
|
|||||||
const columnify = require("columnify");
|
const columnify = require("columnify");
|
||||||
const chalk = require("chalk");
|
const chalk = require("chalk");
|
||||||
|
|
||||||
const myGit = require('../branches');
|
const myGit = require("../branches");
|
||||||
const log = require('../log');
|
const log = require("../log");
|
||||||
|
|
||||||
const iconFor = (branch, branches) => {
|
const iconFor = (branch, branches) => {
|
||||||
if (branch.done) return "✅";
|
if (branch.done) return "✅";
|
||||||
@ -18,25 +18,22 @@ const iconFor = ( branch, branches ) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return "🙋";
|
return "🙋";
|
||||||
|
};
|
||||||
|
|
||||||
}
|
const decorateCurrent = async (branch) => {
|
||||||
|
if (branch !== (await myGit.currentBranch())) return branch;
|
||||||
const decorateCurrent = async branch => {
|
|
||||||
if( branch !== await myGit.currentBranch() ) return branch;
|
|
||||||
|
|
||||||
return chalk.underline.bold(branch);
|
return chalk.underline.bold(branch);
|
||||||
}
|
};
|
||||||
|
|
||||||
async function printNeedsRebasing() {
|
async function printNeedsRebasing() {
|
||||||
const needsRebasing = await myGit.needsRebasing();
|
const needsRebasing = await myGit.needsRebasing();
|
||||||
|
|
||||||
if (!needsRebasing.length) return false;
|
if (!needsRebasing.length) return false;
|
||||||
|
|
||||||
log.subtitle(':arrow_heading_up: needs rebasing');
|
log.subtitle(":arrow_heading_up: needs rebasing");
|
||||||
const b = await Promise.all(
|
const b = await Promise.all(needsRebasing.map(decorateCurrent));
|
||||||
needsRebasing.map( decorateCurrent )
|
log.info("\t", b.join(", "));
|
||||||
);
|
|
||||||
log.info( "\t", b.join(', ') );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -46,31 +43,29 @@ async function printNeedsMerging() {
|
|||||||
|
|
||||||
if (!needsMerging.length) return false;
|
if (!needsMerging.length) return false;
|
||||||
|
|
||||||
log.subtitle(':thumbsup: ready to be merged');
|
log.subtitle(":thumbsup: ready to be merged");
|
||||||
log.info( "\t", needsMerging.map( x => x.join('->') ).join(', ') );
|
log.info("\t", needsMerging.map((x) => x.join("->")).join(", "));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function printActionables() {
|
async function printActionables() {
|
||||||
|
|
||||||
log.title(":point_right: What's next?");
|
log.title(":point_right: What's next?");
|
||||||
|
|
||||||
let something = false;
|
let something = false;
|
||||||
const accumSomething = (value) => something ||= value;
|
const accumSomething = (value) => (something ||= value);
|
||||||
|
|
||||||
accumSomething( await printNeedsRebasing() );
|
|
||||||
|
|
||||||
accumSomething(await printNeedsMerging());
|
accumSomething(await printNeedsMerging());
|
||||||
|
|
||||||
|
accumSomething(await printNeedsRebasing());
|
||||||
|
|
||||||
const canBeDeleted = await myGit.canBeDeleted();
|
const canBeDeleted = await myGit.canBeDeleted();
|
||||||
|
|
||||||
if (canBeDeleted.length) {
|
if (canBeDeleted.length) {
|
||||||
something = true;
|
something = true;
|
||||||
|
|
||||||
log.subtitle(':recycle: branches that can be deleted');
|
log.subtitle(":recycle: branches that can be deleted");
|
||||||
log.info( "\t", canBeDeleted.join(', ') );
|
log.info("\t", canBeDeleted.join(", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
const canBeWorkedOn = await myGit.canBeWorkedOn();
|
const canBeWorkedOn = await myGit.canBeWorkedOn();
|
||||||
@ -78,17 +73,14 @@ async function printActionables() {
|
|||||||
if (canBeWorkedOn.length) {
|
if (canBeWorkedOn.length) {
|
||||||
something = true;
|
something = true;
|
||||||
|
|
||||||
log.subtitle(':hammer: ready to be worked on');
|
log.subtitle(":hammer: ready to be worked on");
|
||||||
const b = await Promise.all(
|
const b = await Promise.all(canBeWorkedOn.map(decorateCurrent));
|
||||||
canBeWorkedOn.map( decorateCurrent )
|
log.info("\t", b.join(", "));
|
||||||
);
|
|
||||||
log.info( "\t", b.join(', ') );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!something) {
|
if (!something) {
|
||||||
log.info("nothing? :shrug:");
|
log.info("nothing? :shrug:");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = async () => {
|
module.exports = async () => {
|
||||||
@ -98,9 +90,7 @@ module.exports = async () => {
|
|||||||
let color = branches[dep].done ? chalk.green : chalk.red;
|
let color = branches[dep].done ? chalk.green : chalk.red;
|
||||||
|
|
||||||
let contains = await Git().raw("branch", "--contains", dep);
|
let contains = await Git().raw("branch", "--contains", dep);
|
||||||
contains = contains
|
contains = contains.split("\n").map((x) => x.trim().replace("* ", ""));
|
||||||
.split("\n")
|
|
||||||
.map((x) => x.trim().replace("* ", ""));
|
|
||||||
|
|
||||||
if (contains.includes(current)) color = color.underline;
|
if (contains.includes(current)) color = color.underline;
|
||||||
|
|
||||||
@ -111,9 +101,7 @@ module.exports = async () => {
|
|||||||
let color = branches[up].done ? chalk.green : chalk.red;
|
let color = branches[up].done ? chalk.green : chalk.red;
|
||||||
|
|
||||||
let contains = await Git().raw("branch", "--contains", current);
|
let contains = await Git().raw("branch", "--contains", current);
|
||||||
contains = contains
|
contains = contains.split("\n").map((x) => x.trim().replace("* ", ""));
|
||||||
.split("\n")
|
|
||||||
.map((x) => x.trim().replace("* ", ""));
|
|
||||||
|
|
||||||
if (contains.includes(up)) color = color.underline;
|
if (contains.includes(up)) color = color.underline;
|
||||||
|
|
||||||
@ -128,7 +116,7 @@ module.exports = async () => {
|
|||||||
console.log(
|
console.log(
|
||||||
iconFor(branch, branches),
|
iconFor(branch, branches),
|
||||||
chalk.blue(branch.name),
|
chalk.blue(branch.name),
|
||||||
branch.current ? "👷" : ' '
|
branch.current ? "👷" : " "
|
||||||
);
|
);
|
||||||
console.log(`\tbase: ${chalk.magenta(branch.base ?? "<none>")}`);
|
console.log(`\tbase: ${chalk.magenta(branch.base ?? "<none>")}`);
|
||||||
|
|
||||||
@ -145,9 +133,7 @@ module.exports = async () => {
|
|||||||
);
|
);
|
||||||
console.log("\tdependencies:", deps.join(" "));
|
console.log("\tdependencies:", deps.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await printActionables();
|
await printActionables();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
12
src/log.js
12
src/log.js
@ -1,12 +1,14 @@
|
|||||||
const emoji = require('node-emoji');
|
const emoji = require("node-emoji");
|
||||||
const chalk = require("chalk");
|
const chalk = require("chalk");
|
||||||
|
|
||||||
function groomLog(...entries) {
|
function groomLog(...entries) {
|
||||||
console.log( ...(entries.map(emoji.emojify)) );
|
console.log(...entries.map(emoji.emojify));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
info: groomLog,
|
info: groomLog,
|
||||||
title: title => groomLog("\n",chalk.blue.bold(title)),
|
title: (title) => groomLog("\n", chalk.blue.bold(title)),
|
||||||
subtitle: title => groomLog("\n",chalk.blue(title)),
|
subtitle: (title) => groomLog("\n", chalk.blue(title)),
|
||||||
}
|
error: (message) => groomLog(":skull:", chalk.red(message)),
|
||||||
|
success: (message) => groomLog(":sparkles:", chalk.green(message)),
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user