-
Notifications
You must be signed in to change notification settings - Fork 935
/
Copy pathcli.js
executable file
·126 lines (112 loc) · 2.99 KB
/
cli.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env node
require('babel-polyfill'); // eslint-disable-line import/no-unassigned-import
// npm modules
const core = require('@commitlint/core');
const chalk = require('chalk');
const meow = require('meow');
const pick = require('lodash').pick;
const stdin = require('get-stdin');
const pkg = require('./package');
const help = require('./help');
/**
* Behavioural rules
*/
const rules = {
fromStdin: (input, flags) =>
input.length === 0 &&
typeof flags.from !== 'string' &&
typeof flags.to !== 'string' &&
!flags.edit
};
const configuration = {
string: ['from', 'to', 'extends'],
boolean: ['edit', 'help', 'version', 'quiet', 'color'],
alias: {
c: 'color',
e: 'edit',
f: 'from',
t: 'to',
q: 'quiet',
h: 'help',
v: 'version',
x: 'extends'
},
description: {
color: 'toggle colored output',
edit: 'read last commit message found in ./git/COMMIT_EDITMSG',
extends: 'array of shareable configurations to extend',
from: 'lower end of the commit range to lint; applies if edit=false',
to: 'upper end of the commit range to lint; applies if edit=false',
quiet: 'toggle console output'
},
default: {
color: true,
edit: false,
from: null,
to: null,
quiet: false
},
unknown(arg) {
throw new Error(`unknown flags: ${arg}`);
}
};
const cli = meow(
{
help: `[input] reads from stdin if --edit, --from and --to are omitted\n${help(
configuration
)}`,
description: `${pkg.name}@${pkg.version} - ${pkg.description}`
},
configuration
);
const load = seed => core.load(seed);
function main(options) {
const raw = options.input;
const flags = options.flags;
const fromStdin = rules.fromStdin(raw, flags);
const range = pick(flags, 'edit', 'from', 'to');
const input = fromStdin ? stdin() : core.read(range);
const fmt = new chalk.constructor({enabled: flags.color});
return input.then(raw => (Array.isArray(raw) ? raw : [raw])).then(messages =>
Promise.all(
messages.map(commit => {
return load(getSeed(flags))
.then(opts => core.lint(commit, opts.rules))
.then(report => {
const formatted = core.format(report, {color: flags.color});
if (!flags.quiet) {
console.log(
`${fmt.grey('⧗')} input: ${fmt.bold(commit.split('\n')[0])}`
);
console.log(formatted.join('\n'));
}
if (report.errors.length > 0) {
const error = new Error(formatted[formatted.length - 1]);
error.type = pkg.name;
throw error;
}
return console.log('');
});
})
)
);
}
function getSeed(seed) {
const e = Array.isArray(seed.extends) ? seed.extends : [seed.extends];
const n = e.filter(i => typeof i === 'string');
return n.length > 0 ? {extends: n} : {};
}
// Start the engine
main(cli).catch(err =>
setTimeout(() => {
if (err.type === pkg.name) {
process.exit(1);
}
throw err;
})
);
// Catch unhandled rejections globally
process.on('unhandledRejection', (reason, promise) => {
console.log('Unhandled Rejection at: Promise ', promise, ' reason: ', reason);
throw reason;
});