UNPKG

2.4 kBJavaScriptView Raw
1const rpad = require('pad-right');
2
3const GAP = 4;
4const __ = ' ';
5const ALL = '__all__';
6const DEF = '__default__';
7const NL = '\n';
8
9function format(arr) {
10 if (!arr.length) return '';
11 let len = maxLen( arr.map(x => x[0]) ) + GAP;
12 let join = a => rpad(a[0], len, ' ') + a[1] + (a[2] == null ? '' : ` (default ${a[2]})`);
13 return arr.map(join);
14}
15
16function maxLen(arr) {
17 let c=0, d=0, l=0, i=arr.length;
18 if (i) while (i--) {
19 d = arr[i].length;
20 if (d > c) {
21 l = i; c = d;
22 }
23 }
24 return arr[l].length;
25}
26
27function noop(s) {
28 return s;
29}
30
31function section(str, arr, fn) {
32 if (!arr || !arr.length) return '';
33 let i=0, out='';
34 out += (NL + __ + str);
35 for (; i < arr.length; i++) {
36 out += (NL + __ + __ + fn(arr[i]));
37 }
38 return out + NL;
39}
40
41exports.help = function (bin, tree, key) {
42 let out='', cmd=tree[key], pfx=`$ ${bin}`, all=tree[ALL];
43 let prefix = s => `${pfx} ${s}`;
44
45 // update ALL & CMD options
46 all.options.push(['-h, --help', 'Displays this message']);
47 cmd.options = (cmd.options || []).concat(all.options);
48
49 // write options placeholder
50 (cmd.options.length > 0) && (cmd.usage += ' [options]');
51
52 // description ~> text only; usage ~> prefixed
53 out += section('Description', cmd.describe, noop);
54 out += section('Usage', [cmd.usage], prefix);
55
56 if (key === DEF) {
57 // General help :: print all non-internal commands & their 1st line of text
58 let cmds = Object.keys(tree).filter(k => !/__/.test(k));
59 let text = cmds.map(k => [k, (tree[k].describe || [''])[0]]);
60 out += section('Available Commands', format(text), noop);
61
62 out += (NL + __ + 'For more info, run any command with the `--help` flag');
63 cmds.slice(0, 2).forEach(k => {
64 out += (NL + __ + __ + `${pfx} ${k} --help`);
65 });
66 out += NL;
67 }
68
69 out += section('Options', format(cmd.options), noop);
70 out += section('Examples', cmd.examples.map(prefix), noop);
71
72 return out;
73}
74
75exports.error = function (bin, str, num=1) {
76 let out = section('ERROR', [str], noop);
77 out += (NL + __ + `Run \`$ ${bin} --help\` for more info.` + NL);
78 console.error(out);
79 process.exit(num);
80}
81
82// Strips leading `-|--` & extra space(s)
83exports.parse = function (str) {
84 return (str || '').split(/^-{1,2}|,|\s+-{1,2}|\s+/).filter(Boolean);
85}
86
87// @see https://stackoverflow.com/a/18914855/3577474
88exports.sentences = function (str) {
89 return (str || '').replace(/([.?!])\s*(?=[A-Z])/g, '$1|').split('|');
90}