Skip to content

Commit

Permalink
Merge pull request #12 from Elao/drop-interactive-mode
Browse files Browse the repository at this point in the history
Drop interactive mode
  • Loading branch information
chalasr authored Jun 28, 2017
2 parents cd6c57e + d995bde commit a48061c
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 65 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ As [recommended by GitHub](https://github.com/blog/180-local-github-config), Gad

### Commands

In your projet repository, just enter `gad`.

| Command | Description |
|---|---|
| __sprint__ | Show the state of the current sprint |
| __sprints__ | Show the state of all sprints |
| __backlog__ | Show the state of the backlog |
| __review__ | Display PullRequest that are awaiting your review |
| __changelog__ | Generate a markdown changelog of the current sprint |
| __estimate__ | Show stories that are missing estimation |
| __status__ | Show the status of the repository |
| __help__ | Show list of commands |
| __exit__ | Quit the dashboard |
In your projet repository, just enter `gad [command] (options)`.

| Command | Description | Options |
|---|---|---|
| __sprint__ | Show the state of the current sprint | __sprint__ `-s=-1` Show the previous sprint |
| __sprints__ | Show the state of all sprints | __limit__ `-l=2` limit the number of sprint to display |
| __backlog__ | Show the state of the backlog | |
| __review__ | Display PullRequest that are awaiting your review | |
| __changelog__ | Generate a markdown changelog of the current sprint | __all__ `--all` include open issues in the changelog. __sprint__ `-s=-2` Show the changelog from two sprints ago |
| __estimate__ | Show stories that are missing estimation | |
| __status__ | Show the status of the repository | |
| __help__ | Show list of commands | |
| __exit__ | Quit the dashboard | |

### Options

Expand Down
10 changes: 8 additions & 2 deletions gad.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@

const { execSync } = require('child_process');
const { homedir } = require('os');
const minimist = require('minimist');
const GithubAgileDashboard = require('./src/GithubAgileDashboard');
const { red } = require('./src/Util/colors');

function lookup(command) { try { return execSync(command).toString().trim(); } catch (error) { return ''; } }
function remote(url) { return (new RegExp('[email protected]:(.+)\\/(.+)\\.git', 'ig').exec(url) || new Array(3).fill(null)).slice(1); }

process.on('uncaughtException', function onError(error) { console.error(red(error.message)); process.exit(1); });

const [defaultOwner, defaultRepo] = remote(lookup('git -C . config --get remote.origin.url'));
const { owner, repo, user, password, cacheDir, _: commands} = require('minimist')(process.argv.slice(2), {
const { owner, repo, user, password, cacheDir, _: command} = minimist(process.argv.slice(2), {
stopEarly: true,
default: {
owner: defaultOwner,
repo: defaultRepo,
Expand All @@ -26,4 +32,4 @@ const { owner, repo, user, password, cacheDir, _: commands} = require('minimist'
}
});

module.exports = new (require('./src/GithubAgileDashboard'))(owner, repo, user, password, cacheDir, commands);
module.exports = new GithubAgileDashboard(owner, repo, user, password, cacheDir, command.join(' '));
44 changes: 33 additions & 11 deletions src/CLI.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const EventEmitter = require('events');
const Readline = require('readline');
const minimist = require('minimist');

class CLI extends EventEmitter {
/**
Expand All @@ -9,14 +10,14 @@ class CLI extends EventEmitter {

/**
* @param {String} prompt
* @param {Array} commandStack command stack
* @param {Array} commandStack Command stack
*/
constructor(prompt = '', commandStack = []) {
super();

const { stdin, stdout } = process;

this.commands = new Set();
this.commands = new Map();
this.readline = Readline.createInterface({ input: stdin, output: stdout, prompt });
this.commandStack = commandStack;
this.ready = false;
Expand All @@ -37,15 +38,31 @@ class CLI extends EventEmitter {
*
* @param {String} name
* @param {Function} callback
* @param {Object} options
*/
on(name, callback) {
on(name, callback, options = {}) {
super.on(name, callback);

if (CLI.RESERVED.indexOf(name) < 0) {
this.commands.add(name);
this.commands.set(name, { default: options, alias: this.getAlias(options) });
}
}

/**
* Create alias automatically
*
* @param {Object} options
*
* @return {Object}
*/
getAlias(options) {
const alias = {};

Object.keys(options).forEach(option => alias[option[0]] = option);

return alias;
}

/**
* Mark as ready
*/
Expand All @@ -59,7 +76,8 @@ class CLI extends EventEmitter {
let line;

while (line = this.commandStack.shift()) {
this.readline.write(`${line}\r\n`);
this.readline.prompt();
this.readline.write(`${line.trim()}\r\n`);
}
}
}
Expand All @@ -77,8 +95,8 @@ class CLI extends EventEmitter {
* Display command result
*/
result(message) {
this.write(typeof message === 'string' ? message : message.join('\r\n'));
this.readline.prompt();
this.write('\r\n' + (typeof message === 'string' ? message : message.join('\r\n')) + '\r\n');
setImmediate(this.close);
}

/**
Expand All @@ -96,11 +114,13 @@ class CLI extends EventEmitter {
* @return {String}
*/
getCommand(input) {
if (this.commands.has(input.trim())) {
return input;
const [ command, ...options] = input.split(' ');

if (!this.commands.has(command)) {
return { command: 'unknown' };
}

return 'unknown';
return { command, options: minimist(options, this.commands.get(command)) };
}

/**
Expand All @@ -118,7 +138,9 @@ class CLI extends EventEmitter {
* @param {String} line
*/
onLine(line) {
this.emit(this.getCommand(line) || 'unknown');
const { command, options } = this.getCommand(line);

this.emit(command || 'unknown', options);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Display/BurnDownChart.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class BurnDownChart {
display() {
const { dayWidth, gutter } = this.constructor;
const burnDown = this.getBurnDown(this.milestone);
const labelLength = Array.from(burnDown.keys()).reduce((max, label) => Math.max(label.length, max), 0);
const labelLength = Math.max(Array.from(burnDown.keys()).reduce((max, label) => Math.max(label.length, max), 0), 1);
const maxPoints = Math.ceil(this.milestone.points);
const pointsPerDay = maxPoints / burnDown.size;
const lines = [
Expand Down
32 changes: 23 additions & 9 deletions src/GitHub/Milestone.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const Issue = require('./Issue');
const DateUtil = require('../Util/DateUtil');
const BurnDownChart = require('../Display/BurnDownChart');
const DateUtil = require('../Util/DateUtil');
const { green, yellow } = require('../Util/colors');

class Milestone {
/**
Expand Down Expand Up @@ -144,7 +145,16 @@ class Milestone {
displaySprint() {
const { title, length, done, todo, inProgress, readyToReview, progress, points } = this;

return `${title} ・ 📉 ${(progress * 100).toFixed(2)}% ・ 📫 ${todo}pts ・ 🚧 ${inProgress}pts ・ 🔍 ${readyToReview}pts ・ ✅ ${done}pts ・ (${length} stories ・ ${points}pts)`;
return [
title,
`${green(length)} stories`,
`${yellow(points)} points`,
`📉 ${(progress * 100).toFixed(2)}%`,
`📫 ${todo}pts`,
`🚧 ${inProgress}pts`,
`🔍 ${readyToReview}pts`,
`✅ ${done}pts`,
].join(' ・ ');
}

/**
Expand All @@ -155,7 +165,7 @@ class Milestone {
displayBacklog() {
const { title, length, points } = this;

return `${title} ・ 📇 ${length} stories ・ ${points} points`;
return `${title} ・ 📇 ${green(length)} stories ・ ${yellow(points)} points`;
}

/**
Expand All @@ -170,14 +180,18 @@ class Milestone {
/**
* Returns a changelog of the sprint
*
* @param {Boolean} all Display all issue (and not just those that are done)
*
* @return {Array}
*/
displayChangelog() {
return ['## Changelog:'].concat(
this.getIssueByStatus('done')
.sort(Issue.sortByPoint)
.map(issue => `- ${issue.title}`)
);
displayChangelog(all = false) {
const issues = all ? this.issues : this.getIssueByStatus('done');

return [`# ${this.title}`, '## Changelog '].concat(
issues
.sort(Issue.sortByPoint)
.map(issue => `- ${issue.title}`)
).join('\r\n');
}

}
Expand Down
31 changes: 27 additions & 4 deletions src/GitHub/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,36 @@ class Project {
}

/**
* Get current milestone
* Get sprint by index
*
* @param {Number} index If null: current sprint. If negative: previous sprint from current. If position: number of the sprint.
* @param {Date} date
*
* @return {Milestone}
*/
getCurrentMilestone(date = DateUtil.day()) {
return this.getSprints().find(milestone => milestone.isCurrent(date));
getSprint(number = null, date = DateUtil.day()) {
const sprints = this.getSprints();

if (!number) {
return sprints.find(milestone => milestone.isCurrent(date));
}

if (number > 0) {
if (typeof sprints[number - 1] === 'undefined') {
throw new Error(`No sprint ${number}: only ${sprints.length} sprints found.`);
}

return sprints[number - 1];
} else {
const date = DateUtil.day();
const current = sprints.findIndex(milestone => milestone.isCurrent(date));

if (typeof sprints[current + number] === 'undefined') {
throw new Error(`No sprint ${number}.`);
}

return sprints[current + number];
}
}

/**
Expand All @@ -40,7 +62,7 @@ class Project {
* @return {Milestone[]}
*/
getSprints() {
return this.milestones.sort(Milestone.sort).filter(milestone => !milestone.isBacklog());
return this.milestones.filter(milestone => !milestone.isBacklog());
}

/**
Expand Down Expand Up @@ -82,6 +104,7 @@ class Project {
load(issues) {
issues.filter(data => typeof data.pull_request === 'undefined').forEach(this.loadIssue);
issues.filter(data => typeof data.pull_request !== 'undefined').forEach(this.loadPullRequest);
this.milestones.sort(Milestone.sort);
this.getSprints().forEach((milestone, index, sprints) => milestone.previous = sprints[index - 1] || null);
}

Expand Down
Loading

0 comments on commit a48061c

Please sign in to comment.