commander 2.13.0 → 2.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/Readme.md +41 -3
- package/index.js +189 -116
- package/package.json +6 -3
- package/typings/index.d.ts +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,26 @@
|
|
|
1
1
|
|
|
2
|
+
2.15.0 / 2018-03-07
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
* Update downloads badge to point to graph of downloads over time instead of duplicating link to npm
|
|
6
|
+
* Arguments description
|
|
7
|
+
|
|
8
|
+
2.14.1 / 2018-02-07
|
|
9
|
+
==================
|
|
10
|
+
|
|
11
|
+
* Fix typing of help function
|
|
12
|
+
|
|
13
|
+
2.14.0 / 2018-02-05
|
|
14
|
+
==================
|
|
15
|
+
|
|
16
|
+
* only register the option:version event once
|
|
17
|
+
* Fixes issue #727: Passing empty string for option on command is set to undefined
|
|
18
|
+
* enable eqeqeq rule
|
|
19
|
+
* resolves #754 add linter configuration to project
|
|
20
|
+
* resolves #560 respect custom name for version option
|
|
21
|
+
* document how to override the version flag
|
|
22
|
+
* document using options per command
|
|
23
|
+
|
|
2
24
|
2.13.0 / 2018-01-09
|
|
3
25
|
==================
|
|
4
26
|
|
package/Readme.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
[](http://travis-ci.org/tj/commander.js)
|
|
5
5
|
[](https://www.npmjs.org/package/commander)
|
|
6
|
-
[](https://
|
|
6
|
+
[](https://npmcharts.com/compare/commander?minimal=true)
|
|
7
7
|
[](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
8
8
|
|
|
9
9
|
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
## Option parsing
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
|
|
20
20
|
|
|
21
21
|
```js
|
|
22
22
|
#!/usr/bin/env node
|
|
@@ -42,7 +42,7 @@ if (program.bbqSauce) console.log(' - bbq');
|
|
|
42
42
|
console.log(' - %s cheese', program.cheese);
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
|
|
46
46
|
|
|
47
47
|
Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false.
|
|
48
48
|
|
|
@@ -64,6 +64,44 @@ if (program.sauce) console.log(' with sauce');
|
|
|
64
64
|
else console.log(' without sauce');
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
## Version option
|
|
68
|
+
|
|
69
|
+
Calling the `version` implicitly adds the `-V` and `--version` options to the command.
|
|
70
|
+
When either of these options is present, the command prints the version number and exits.
|
|
71
|
+
|
|
72
|
+
$ ./examples/pizza -V
|
|
73
|
+
0.0.1
|
|
74
|
+
|
|
75
|
+
If you want your program to respond to the `-v` option instead of the `-V` option, simply pass custom flags to the `version` method using the same syntax as the `option` method.
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
program
|
|
79
|
+
.version('0.0.1', '-v, --version')
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The version flags can be named anything, but the long option is required.
|
|
83
|
+
|
|
84
|
+
## Command-specific options
|
|
85
|
+
|
|
86
|
+
You can attach options to a command.
|
|
87
|
+
|
|
88
|
+
```js
|
|
89
|
+
#!/usr/bin/env node
|
|
90
|
+
|
|
91
|
+
var program = require('commander');
|
|
92
|
+
|
|
93
|
+
program
|
|
94
|
+
.command('rm <dir>')
|
|
95
|
+
.option('-r, --recursive', 'Remove recursively')
|
|
96
|
+
.action(function (dir, cmd) {
|
|
97
|
+
console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
program.parse(process.argv)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated.
|
|
104
|
+
|
|
67
105
|
## Coercion
|
|
68
106
|
|
|
69
107
|
```js
|
package/index.js
CHANGED
|
@@ -9,6 +9,12 @@ var dirname = path.dirname;
|
|
|
9
9
|
var basename = path.basename;
|
|
10
10
|
var fs = require('fs');
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Inherit `Command` from `EventEmitter.prototype`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
require('util').inherits(Command, EventEmitter);
|
|
17
|
+
|
|
12
18
|
/**
|
|
13
19
|
* Expose the root command.
|
|
14
20
|
*/
|
|
@@ -68,7 +74,7 @@ Option.prototype.name = function() {
|
|
|
68
74
|
*/
|
|
69
75
|
|
|
70
76
|
Option.prototype.attributeName = function() {
|
|
71
|
-
return camelcase(
|
|
77
|
+
return camelcase(this.name());
|
|
72
78
|
};
|
|
73
79
|
|
|
74
80
|
/**
|
|
@@ -80,7 +86,7 @@ Option.prototype.attributeName = function() {
|
|
|
80
86
|
*/
|
|
81
87
|
|
|
82
88
|
Option.prototype.is = function(arg) {
|
|
83
|
-
return
|
|
89
|
+
return this.short === arg || this.long === arg;
|
|
84
90
|
};
|
|
85
91
|
|
|
86
92
|
/**
|
|
@@ -99,12 +105,6 @@ function Command(name) {
|
|
|
99
105
|
this._name = name || '';
|
|
100
106
|
}
|
|
101
107
|
|
|
102
|
-
/**
|
|
103
|
-
* Inherit from `EventEmitter.prototype`.
|
|
104
|
-
*/
|
|
105
|
-
|
|
106
|
-
Command.prototype.__proto__ = EventEmitter.prototype;
|
|
107
|
-
|
|
108
108
|
/**
|
|
109
109
|
* Add command `name`.
|
|
110
110
|
*
|
|
@@ -167,7 +167,7 @@ Command.prototype.__proto__ = EventEmitter.prototype;
|
|
|
167
167
|
*/
|
|
168
168
|
|
|
169
169
|
Command.prototype.command = function(name, desc, opts) {
|
|
170
|
-
if(typeof desc === 'object' && desc !== null){
|
|
170
|
+
if (typeof desc === 'object' && desc !== null) {
|
|
171
171
|
opts = desc;
|
|
172
172
|
desc = null;
|
|
173
173
|
}
|
|
@@ -196,7 +196,7 @@ Command.prototype.command = function(name, desc, opts) {
|
|
|
196
196
|
* @api public
|
|
197
197
|
*/
|
|
198
198
|
|
|
199
|
-
Command.prototype.arguments = function
|
|
199
|
+
Command.prototype.arguments = function(desc) {
|
|
200
200
|
return this.parseExpectedArgs(desc.split(/ +/));
|
|
201
201
|
};
|
|
202
202
|
|
|
@@ -292,7 +292,7 @@ Command.prototype.action = function(fn) {
|
|
|
292
292
|
if (parsed.args.length) args = parsed.args.concat(args);
|
|
293
293
|
|
|
294
294
|
self._args.forEach(function(arg, i) {
|
|
295
|
-
if (arg.required &&
|
|
295
|
+
if (arg.required && args[i] == null) {
|
|
296
296
|
self.missingArgument(arg.name);
|
|
297
297
|
} else if (arg.variadic) {
|
|
298
298
|
if (i !== self._args.length - 1) {
|
|
@@ -371,32 +371,31 @@ Command.prototype.action = function(fn) {
|
|
|
371
371
|
*/
|
|
372
372
|
|
|
373
373
|
Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
374
|
-
var self = this
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
374
|
+
var self = this,
|
|
375
|
+
option = new Option(flags, description),
|
|
376
|
+
oname = option.name(),
|
|
377
|
+
name = option.attributeName();
|
|
378
378
|
|
|
379
379
|
// default as 3rd arg
|
|
380
|
-
if (typeof fn
|
|
380
|
+
if (typeof fn !== 'function') {
|
|
381
381
|
if (fn instanceof RegExp) {
|
|
382
382
|
var regex = fn;
|
|
383
383
|
fn = function(val, def) {
|
|
384
384
|
var m = regex.exec(val);
|
|
385
385
|
return m ? m[0] : def;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
else {
|
|
386
|
+
};
|
|
387
|
+
} else {
|
|
389
388
|
defaultValue = fn;
|
|
390
389
|
fn = null;
|
|
391
390
|
}
|
|
392
391
|
}
|
|
393
392
|
|
|
394
393
|
// preassign default value only for --no-*, [optional], or <required>
|
|
395
|
-
if (
|
|
394
|
+
if (!option.bool || option.optional || option.required) {
|
|
396
395
|
// when --no-* we make sure default is true
|
|
397
|
-
if (
|
|
396
|
+
if (!option.bool) defaultValue = true;
|
|
398
397
|
// preassign only if we have a default
|
|
399
|
-
if (
|
|
398
|
+
if (defaultValue !== undefined) {
|
|
400
399
|
self[name] = defaultValue;
|
|
401
400
|
option.defaultValue = defaultValue;
|
|
402
401
|
}
|
|
@@ -409,21 +408,21 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
|
409
408
|
// and conditionally invoke the callback
|
|
410
409
|
this.on('option:' + oname, function(val) {
|
|
411
410
|
// coercion
|
|
412
|
-
if (
|
|
413
|
-
? defaultValue
|
|
414
|
-
|
|
411
|
+
if (val !== null && fn) {
|
|
412
|
+
val = fn(val, self[name] === undefined ? defaultValue : self[name]);
|
|
413
|
+
}
|
|
415
414
|
|
|
416
415
|
// unassigned or bool
|
|
417
|
-
if (
|
|
416
|
+
if (typeof self[name] === 'boolean' || typeof self[name] === 'undefined') {
|
|
418
417
|
// if no value, bool true, and we have a default, then use it!
|
|
419
|
-
if (
|
|
418
|
+
if (val == null) {
|
|
420
419
|
self[name] = option.bool
|
|
421
420
|
? defaultValue || true
|
|
422
421
|
: false;
|
|
423
422
|
} else {
|
|
424
423
|
self[name] = val;
|
|
425
424
|
}
|
|
426
|
-
} else if (
|
|
425
|
+
} else if (val !== null) {
|
|
427
426
|
// reassign
|
|
428
427
|
self[name] = val;
|
|
429
428
|
}
|
|
@@ -440,8 +439,8 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
|
440
439
|
* @api public
|
|
441
440
|
*/
|
|
442
441
|
Command.prototype.allowUnknownOption = function(arg) {
|
|
443
|
-
|
|
444
|
-
|
|
442
|
+
this._allowUnknownOption = arguments.length === 0 || arg;
|
|
443
|
+
return this;
|
|
445
444
|
};
|
|
446
445
|
|
|
447
446
|
/**
|
|
@@ -485,7 +484,7 @@ Command.prototype.parse = function(argv) {
|
|
|
485
484
|
})[0];
|
|
486
485
|
}
|
|
487
486
|
|
|
488
|
-
if (this._execs[name] && typeof this._execs[name]
|
|
487
|
+
if (this._execs[name] && typeof this._execs[name] !== 'function') {
|
|
489
488
|
return this.executeSubCommand(argv, args, parsed.unknown);
|
|
490
489
|
} else if (aliasCommand) {
|
|
491
490
|
// is alias of a subCommand
|
|
@@ -513,10 +512,10 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
513
512
|
args = args.concat(unknown);
|
|
514
513
|
|
|
515
514
|
if (!args.length) this.help();
|
|
516
|
-
if (
|
|
515
|
+
if (args[0] === 'help' && args.length === 1) this.help();
|
|
517
516
|
|
|
518
517
|
// <cmd> --help
|
|
519
|
-
if (
|
|
518
|
+
if (args[0] === 'help') {
|
|
520
519
|
args[0] = args[1];
|
|
521
520
|
args[1] = '--help';
|
|
522
521
|
}
|
|
@@ -526,15 +525,14 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
526
525
|
// name of the subcommand, link `pm-install`
|
|
527
526
|
var bin = basename(f, '.js') + '-' + args[0];
|
|
528
527
|
|
|
529
|
-
|
|
530
528
|
// In case of globally installed, get the base dir where executable
|
|
531
529
|
// subcommand file should be located at
|
|
532
|
-
var baseDir
|
|
533
|
-
|
|
530
|
+
var baseDir,
|
|
531
|
+
link = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f;
|
|
534
532
|
|
|
535
533
|
// when symbolink is relative path
|
|
536
534
|
if (link !== f && link.charAt(0) !== '/') {
|
|
537
|
-
link = path.join(dirname(f), link)
|
|
535
|
+
link = path.join(dirname(f), link);
|
|
538
536
|
}
|
|
539
537
|
baseDir = dirname(link);
|
|
540
538
|
|
|
@@ -565,22 +563,22 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
565
563
|
}
|
|
566
564
|
} else {
|
|
567
565
|
args.unshift(bin);
|
|
568
|
-
proc = spawn(process.execPath, args, { stdio: 'inherit'});
|
|
566
|
+
proc = spawn(process.execPath, args, { stdio: 'inherit' });
|
|
569
567
|
}
|
|
570
568
|
|
|
571
569
|
var signals = ['SIGUSR1', 'SIGUSR2', 'SIGTERM', 'SIGINT', 'SIGHUP'];
|
|
572
570
|
signals.forEach(function(signal) {
|
|
573
|
-
process.on(signal, function(){
|
|
574
|
-
if (
|
|
571
|
+
process.on(signal, function() {
|
|
572
|
+
if (proc.killed === false && proc.exitCode === null) {
|
|
575
573
|
proc.kill(signal);
|
|
576
574
|
}
|
|
577
575
|
});
|
|
578
576
|
});
|
|
579
577
|
proc.on('close', process.exit.bind(process));
|
|
580
578
|
proc.on('error', function(err) {
|
|
581
|
-
if (err.code
|
|
579
|
+
if (err.code === 'ENOENT') {
|
|
582
580
|
console.error('\n %s(1) does not exist, try --help\n', bin);
|
|
583
|
-
} else if (err.code
|
|
581
|
+
} else if (err.code === 'EACCES') {
|
|
584
582
|
console.error('\n %s(1) not executable. try chmod or run with root\n', bin);
|
|
585
583
|
}
|
|
586
584
|
process.exit(1);
|
|
@@ -601,15 +599,15 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
601
599
|
*/
|
|
602
600
|
|
|
603
601
|
Command.prototype.normalize = function(args) {
|
|
604
|
-
var ret = []
|
|
605
|
-
,
|
|
606
|
-
,
|
|
607
|
-
|
|
602
|
+
var ret = [],
|
|
603
|
+
arg,
|
|
604
|
+
lastOpt,
|
|
605
|
+
index;
|
|
608
606
|
|
|
609
607
|
for (var i = 0, len = args.length; i < len; ++i) {
|
|
610
608
|
arg = args[i];
|
|
611
609
|
if (i > 0) {
|
|
612
|
-
lastOpt = this.optionFor(args[i-1]);
|
|
610
|
+
lastOpt = this.optionFor(args[i - 1]);
|
|
613
611
|
}
|
|
614
612
|
|
|
615
613
|
if (arg === '--') {
|
|
@@ -618,7 +616,7 @@ Command.prototype.normalize = function(args) {
|
|
|
618
616
|
break;
|
|
619
617
|
} else if (lastOpt && lastOpt.required) {
|
|
620
618
|
ret.push(arg);
|
|
621
|
-
} else if (arg.length > 1 &&
|
|
619
|
+
} else if (arg.length > 1 && arg[0] === '-' && arg[1] !== '-') {
|
|
622
620
|
arg.slice(1).split('').forEach(function(c) {
|
|
623
621
|
ret.push('-' + c);
|
|
624
622
|
});
|
|
@@ -693,11 +691,11 @@ Command.prototype.optionFor = function(arg) {
|
|
|
693
691
|
*/
|
|
694
692
|
|
|
695
693
|
Command.prototype.parseOptions = function(argv) {
|
|
696
|
-
var args = []
|
|
697
|
-
|
|
698
|
-
,
|
|
699
|
-
,
|
|
700
|
-
|
|
694
|
+
var args = [],
|
|
695
|
+
len = argv.length,
|
|
696
|
+
literal,
|
|
697
|
+
option,
|
|
698
|
+
arg;
|
|
701
699
|
|
|
702
700
|
var unknownOptions = [];
|
|
703
701
|
|
|
@@ -711,7 +709,7 @@ Command.prototype.parseOptions = function(argv) {
|
|
|
711
709
|
continue;
|
|
712
710
|
}
|
|
713
711
|
|
|
714
|
-
if ('--'
|
|
712
|
+
if (arg === '--') {
|
|
715
713
|
literal = true;
|
|
716
714
|
continue;
|
|
717
715
|
}
|
|
@@ -724,12 +722,12 @@ Command.prototype.parseOptions = function(argv) {
|
|
|
724
722
|
// requires arg
|
|
725
723
|
if (option.required) {
|
|
726
724
|
arg = argv[++i];
|
|
727
|
-
if (
|
|
725
|
+
if (arg == null) return this.optionMissingArgument(option);
|
|
728
726
|
this.emit('option:' + option.name(), arg);
|
|
729
727
|
// optional arg
|
|
730
728
|
} else if (option.optional) {
|
|
731
|
-
arg = argv[i+1];
|
|
732
|
-
if (
|
|
729
|
+
arg = argv[i + 1];
|
|
730
|
+
if (arg == null || (arg[0] === '-' && arg !== '-')) {
|
|
733
731
|
arg = null;
|
|
734
732
|
} else {
|
|
735
733
|
++i;
|
|
@@ -743,13 +741,13 @@ Command.prototype.parseOptions = function(argv) {
|
|
|
743
741
|
}
|
|
744
742
|
|
|
745
743
|
// looks like an option
|
|
746
|
-
if (arg.length > 1 &&
|
|
744
|
+
if (arg.length > 1 && arg[0] === '-') {
|
|
747
745
|
unknownOptions.push(arg);
|
|
748
746
|
|
|
749
747
|
// If the next argument looks like it might be
|
|
750
748
|
// an argument for this option, we pass it on.
|
|
751
749
|
// If it isn't, then it'll simply be ignored
|
|
752
|
-
if (
|
|
750
|
+
if ((i + 1) < argv.length && argv[i + 1][0] !== '-') {
|
|
753
751
|
unknownOptions.push(argv[++i]);
|
|
754
752
|
}
|
|
755
753
|
continue;
|
|
@@ -769,12 +767,12 @@ Command.prototype.parseOptions = function(argv) {
|
|
|
769
767
|
* @api public
|
|
770
768
|
*/
|
|
771
769
|
Command.prototype.opts = function() {
|
|
772
|
-
var result = {}
|
|
773
|
-
|
|
770
|
+
var result = {},
|
|
771
|
+
len = this.options.length;
|
|
774
772
|
|
|
775
|
-
for (var i = 0
|
|
773
|
+
for (var i = 0; i < len; i++) {
|
|
776
774
|
var key = this.options[i].attributeName();
|
|
777
|
-
result[key] = key ===
|
|
775
|
+
result[key] = key === this._versionOptionName ? this._version : this[key];
|
|
778
776
|
}
|
|
779
777
|
return result;
|
|
780
778
|
};
|
|
@@ -854,11 +852,13 @@ Command.prototype.variadicArgNotLast = function(name) {
|
|
|
854
852
|
*/
|
|
855
853
|
|
|
856
854
|
Command.prototype.version = function(str, flags) {
|
|
857
|
-
if (
|
|
855
|
+
if (arguments.length === 0) return this._version;
|
|
858
856
|
this._version = str;
|
|
859
857
|
flags = flags || '-V, --version';
|
|
860
|
-
|
|
861
|
-
this.
|
|
858
|
+
var versionOption = new Option(flags, 'output the version number');
|
|
859
|
+
this._versionOptionName = versionOption.long.substr(2) || 'version';
|
|
860
|
+
this.options.push(versionOption);
|
|
861
|
+
this.on('option:' + this._versionOptionName, function() {
|
|
862
862
|
process.stdout.write(str + '\n');
|
|
863
863
|
process.exit(0);
|
|
864
864
|
});
|
|
@@ -869,13 +869,15 @@ Command.prototype.version = function(str, flags) {
|
|
|
869
869
|
* Set the description to `str`.
|
|
870
870
|
*
|
|
871
871
|
* @param {String} str
|
|
872
|
+
* @param {Object} argsDescription
|
|
872
873
|
* @return {String|Command}
|
|
873
874
|
* @api public
|
|
874
875
|
*/
|
|
875
876
|
|
|
876
|
-
Command.prototype.description = function(str) {
|
|
877
|
-
if (
|
|
877
|
+
Command.prototype.description = function(str, argsDescription) {
|
|
878
|
+
if (arguments.length === 0) return this._description;
|
|
878
879
|
this._description = str;
|
|
880
|
+
this._argsDescription = argsDescription;
|
|
879
881
|
return this;
|
|
880
882
|
};
|
|
881
883
|
|
|
@@ -889,8 +891,8 @@ Command.prototype.description = function(str) {
|
|
|
889
891
|
|
|
890
892
|
Command.prototype.alias = function(alias) {
|
|
891
893
|
var command = this;
|
|
892
|
-
if(this.commands.length !== 0) {
|
|
893
|
-
command = this.commands[this.commands.length - 1]
|
|
894
|
+
if (this.commands.length !== 0) {
|
|
895
|
+
command = this.commands[this.commands.length - 1];
|
|
894
896
|
}
|
|
895
897
|
|
|
896
898
|
if (arguments.length === 0) return command._alias;
|
|
@@ -914,11 +916,11 @@ Command.prototype.usage = function(str) {
|
|
|
914
916
|
return humanReadableArgName(arg);
|
|
915
917
|
});
|
|
916
918
|
|
|
917
|
-
var usage = '[options]'
|
|
918
|
-
|
|
919
|
-
|
|
919
|
+
var usage = '[options]' +
|
|
920
|
+
(this.commands.length ? ' [command]' : '') +
|
|
921
|
+
(this._args.length ? ' ' + args.join(' ') : '');
|
|
920
922
|
|
|
921
|
-
if (
|
|
923
|
+
if (arguments.length === 0) return this._usage || usage;
|
|
922
924
|
this._usage = str;
|
|
923
925
|
|
|
924
926
|
return this;
|
|
@@ -933,11 +935,50 @@ Command.prototype.usage = function(str) {
|
|
|
933
935
|
*/
|
|
934
936
|
|
|
935
937
|
Command.prototype.name = function(str) {
|
|
936
|
-
if (
|
|
938
|
+
if (arguments.length === 0) return this._name;
|
|
937
939
|
this._name = str;
|
|
938
940
|
return this;
|
|
939
941
|
};
|
|
940
942
|
|
|
943
|
+
/**
|
|
944
|
+
* Return prepared commands.
|
|
945
|
+
*
|
|
946
|
+
* @return {Array}
|
|
947
|
+
* @api private
|
|
948
|
+
*/
|
|
949
|
+
|
|
950
|
+
Command.prototype.prepareCommands = function() {
|
|
951
|
+
return this.commands.filter(function(cmd) {
|
|
952
|
+
return !cmd._noHelp;
|
|
953
|
+
}).map(function(cmd) {
|
|
954
|
+
var args = cmd._args.map(function(arg) {
|
|
955
|
+
return humanReadableArgName(arg);
|
|
956
|
+
}).join(' ');
|
|
957
|
+
|
|
958
|
+
return [
|
|
959
|
+
cmd._name +
|
|
960
|
+
(cmd._alias ? '|' + cmd._alias : '') +
|
|
961
|
+
(cmd.options.length ? ' [options]' : '') +
|
|
962
|
+
(args ? ' ' + args : ''),
|
|
963
|
+
cmd._description
|
|
964
|
+
];
|
|
965
|
+
});
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
/**
|
|
969
|
+
* Return the largest command length.
|
|
970
|
+
*
|
|
971
|
+
* @return {Number}
|
|
972
|
+
* @api private
|
|
973
|
+
*/
|
|
974
|
+
|
|
975
|
+
Command.prototype.largestCommandLength = function() {
|
|
976
|
+
var commands = this.prepareCommands();
|
|
977
|
+
return commands.reduce(function(max, command) {
|
|
978
|
+
return Math.max(max, command[0].length);
|
|
979
|
+
}, 0);
|
|
980
|
+
};
|
|
981
|
+
|
|
941
982
|
/**
|
|
942
983
|
* Return the largest option length.
|
|
943
984
|
*
|
|
@@ -946,11 +987,52 @@ Command.prototype.name = function(str) {
|
|
|
946
987
|
*/
|
|
947
988
|
|
|
948
989
|
Command.prototype.largestOptionLength = function() {
|
|
949
|
-
|
|
990
|
+
var options = [].slice.call(this.options);
|
|
991
|
+
options.push({
|
|
992
|
+
flags: '-h, --help'
|
|
993
|
+
});
|
|
994
|
+
return options.reduce(function(max, option) {
|
|
950
995
|
return Math.max(max, option.flags.length);
|
|
951
996
|
}, 0);
|
|
952
997
|
};
|
|
953
998
|
|
|
999
|
+
/**
|
|
1000
|
+
* Return the largest arg length.
|
|
1001
|
+
*
|
|
1002
|
+
* @return {Number}
|
|
1003
|
+
* @api private
|
|
1004
|
+
*/
|
|
1005
|
+
|
|
1006
|
+
Command.prototype.largestArgLength = function() {
|
|
1007
|
+
return this._args.reduce(function(max, arg) {
|
|
1008
|
+
return Math.max(max, arg.name.length);
|
|
1009
|
+
}, 0);
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
/**
|
|
1013
|
+
* Return the pad width.
|
|
1014
|
+
*
|
|
1015
|
+
* @return {Number}
|
|
1016
|
+
* @api private
|
|
1017
|
+
*/
|
|
1018
|
+
|
|
1019
|
+
Command.prototype.padWidth = function() {
|
|
1020
|
+
var width = this.largestOptionLength();
|
|
1021
|
+
if (this._argsDescription && this._args.length) {
|
|
1022
|
+
if (this.largestArgLength() > width) {
|
|
1023
|
+
width = this.largestArgLength();
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (this.commands && this.commands.length) {
|
|
1028
|
+
if (this.largestCommandLength() > width) {
|
|
1029
|
+
width = this.largestCommandLength();
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
return width;
|
|
1034
|
+
};
|
|
1035
|
+
|
|
954
1036
|
/**
|
|
955
1037
|
* Return help for options.
|
|
956
1038
|
*
|
|
@@ -959,12 +1041,12 @@ Command.prototype.largestOptionLength = function() {
|
|
|
959
1041
|
*/
|
|
960
1042
|
|
|
961
1043
|
Command.prototype.optionHelp = function() {
|
|
962
|
-
var width = this.
|
|
1044
|
+
var width = this.padWidth();
|
|
963
1045
|
|
|
964
1046
|
// Append the help information
|
|
965
1047
|
return this.options.map(function(option) {
|
|
966
|
-
|
|
967
|
-
|
|
1048
|
+
return pad(option.flags, width) + ' ' + option.description +
|
|
1049
|
+
((option.bool && option.defaultValue !== undefined) ? ' (default: ' + option.defaultValue + ')' : '');
|
|
968
1050
|
}).concat([pad('-h, --help', width) + ' ' + 'output usage information'])
|
|
969
1051
|
.join('\n');
|
|
970
1052
|
};
|
|
@@ -979,35 +1061,17 @@ Command.prototype.optionHelp = function() {
|
|
|
979
1061
|
Command.prototype.commandHelp = function() {
|
|
980
1062
|
if (!this.commands.length) return '';
|
|
981
1063
|
|
|
982
|
-
var commands = this.
|
|
983
|
-
|
|
984
|
-
}).map(function(cmd) {
|
|
985
|
-
var args = cmd._args.map(function(arg) {
|
|
986
|
-
return humanReadableArgName(arg);
|
|
987
|
-
}).join(' ');
|
|
988
|
-
|
|
989
|
-
return [
|
|
990
|
-
cmd._name
|
|
991
|
-
+ (cmd._alias ? '|' + cmd._alias : '')
|
|
992
|
-
+ (cmd.options.length ? ' [options]' : '')
|
|
993
|
-
+ (args ? ' ' + args : '')
|
|
994
|
-
, cmd._description
|
|
995
|
-
];
|
|
996
|
-
});
|
|
997
|
-
|
|
998
|
-
var width = commands.reduce(function(max, command) {
|
|
999
|
-
return Math.max(max, command[0].length);
|
|
1000
|
-
}, 0);
|
|
1064
|
+
var commands = this.prepareCommands();
|
|
1065
|
+
var width = this.padWidth();
|
|
1001
1066
|
|
|
1002
1067
|
return [
|
|
1003
|
-
''
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
, commands.map(function(cmd) {
|
|
1068
|
+
' Commands:',
|
|
1069
|
+
'',
|
|
1070
|
+
commands.map(function(cmd) {
|
|
1007
1071
|
var desc = cmd[1] ? ' ' + cmd[1] : '';
|
|
1008
1072
|
return (desc ? pad(cmd[0], width) : cmd[0]) + desc;
|
|
1009
|
-
}).join('\n').replace(/^/gm, ' ')
|
|
1010
|
-
|
|
1073
|
+
}).join('\n').replace(/^/gm, ' '),
|
|
1074
|
+
''
|
|
1011
1075
|
].join('\n');
|
|
1012
1076
|
};
|
|
1013
1077
|
|
|
@@ -1022,9 +1086,20 @@ Command.prototype.helpInformation = function() {
|
|
|
1022
1086
|
var desc = [];
|
|
1023
1087
|
if (this._description) {
|
|
1024
1088
|
desc = [
|
|
1025
|
-
' ' + this._description
|
|
1026
|
-
|
|
1089
|
+
' ' + this._description,
|
|
1090
|
+
''
|
|
1027
1091
|
];
|
|
1092
|
+
|
|
1093
|
+
var argsDescription = this._argsDescription;
|
|
1094
|
+
if (argsDescription && this._args.length) {
|
|
1095
|
+
var width = this.padWidth();
|
|
1096
|
+
desc.push(' Arguments:');
|
|
1097
|
+
desc.push('');
|
|
1098
|
+
this._args.forEach(function(arg) {
|
|
1099
|
+
desc.push(' ' + pad(arg.name, width) + ' ' + argsDescription[arg.name]);
|
|
1100
|
+
});
|
|
1101
|
+
desc.push('');
|
|
1102
|
+
}
|
|
1028
1103
|
}
|
|
1029
1104
|
|
|
1030
1105
|
var cmdName = this._name;
|
|
@@ -1032,9 +1107,9 @@ Command.prototype.helpInformation = function() {
|
|
|
1032
1107
|
cmdName = cmdName + '|' + this._alias;
|
|
1033
1108
|
}
|
|
1034
1109
|
var usage = [
|
|
1110
|
+
'',
|
|
1111
|
+
' Usage: ' + cmdName + ' ' + this.usage(),
|
|
1035
1112
|
''
|
|
1036
|
-
,' Usage: ' + cmdName + ' ' + this.usage()
|
|
1037
|
-
, ''
|
|
1038
1113
|
];
|
|
1039
1114
|
|
|
1040
1115
|
var cmds = [];
|
|
@@ -1042,11 +1117,10 @@ Command.prototype.helpInformation = function() {
|
|
|
1042
1117
|
if (commandHelp) cmds = [commandHelp];
|
|
1043
1118
|
|
|
1044
1119
|
var options = [
|
|
1120
|
+
' Options:',
|
|
1121
|
+
'',
|
|
1122
|
+
'' + this.optionHelp().replace(/^/gm, ' '),
|
|
1045
1123
|
''
|
|
1046
|
-
, ' Options:'
|
|
1047
|
-
, ''
|
|
1048
|
-
, '' + this.optionHelp().replace(/^/gm, ' ')
|
|
1049
|
-
, ''
|
|
1050
1124
|
];
|
|
1051
1125
|
|
|
1052
1126
|
return usage
|
|
@@ -1066,7 +1140,7 @@ Command.prototype.outputHelp = function(cb) {
|
|
|
1066
1140
|
if (!cb) {
|
|
1067
1141
|
cb = function(passthru) {
|
|
1068
1142
|
return passthru;
|
|
1069
|
-
}
|
|
1143
|
+
};
|
|
1070
1144
|
}
|
|
1071
1145
|
process.stdout.write(cb(this.helpInformation()));
|
|
1072
1146
|
this.emit('--help');
|
|
@@ -1122,7 +1196,7 @@ function pad(str, width) {
|
|
|
1122
1196
|
function outputHelpIfNecessary(cmd, options) {
|
|
1123
1197
|
options = options || [];
|
|
1124
1198
|
for (var i = 0; i < options.length; i++) {
|
|
1125
|
-
if (options[i]
|
|
1199
|
+
if (options[i] === '--help' || options[i] === '-h') {
|
|
1126
1200
|
cmd.outputHelp();
|
|
1127
1201
|
process.exit(0);
|
|
1128
1202
|
}
|
|
@@ -1142,7 +1216,7 @@ function humanReadableArgName(arg) {
|
|
|
1142
1216
|
|
|
1143
1217
|
return arg.required
|
|
1144
1218
|
? '<' + nameOutput + '>'
|
|
1145
|
-
: '[' + nameOutput + ']'
|
|
1219
|
+
: '[' + nameOutput + ']';
|
|
1146
1220
|
}
|
|
1147
1221
|
|
|
1148
1222
|
// for versions before node v0.8 when there weren't `fs.existsSync`
|
|
@@ -1155,4 +1229,3 @@ function exists(file) {
|
|
|
1155
1229
|
return false;
|
|
1156
1230
|
}
|
|
1157
1231
|
}
|
|
1158
|
-
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.1",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"url": "https://github.com/tj/commander.js.git"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
+
"lint": "eslint index.js",
|
|
18
19
|
"test": "make test && npm run test-typings",
|
|
19
20
|
"test-typings": "node_modules/typescript/bin/tsc -p tsconfig.json"
|
|
20
21
|
},
|
|
@@ -25,10 +26,12 @@
|
|
|
25
26
|
],
|
|
26
27
|
"dependencies": {},
|
|
27
28
|
"devDependencies": {
|
|
28
|
-
"@types/node": "^7.0.
|
|
29
|
+
"@types/node": "^7.0.55",
|
|
30
|
+
"eslint": "^3.19.0",
|
|
29
31
|
"should": "^11.2.1",
|
|
30
32
|
"sinon": "^2.4.1",
|
|
31
|
-
"
|
|
33
|
+
"standard": "^10.0.3",
|
|
34
|
+
"typescript": "^2.7.2"
|
|
32
35
|
},
|
|
33
36
|
"typings": "typings/index.d.ts"
|
|
34
37
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -271,8 +271,11 @@ declare namespace local {
|
|
|
271
271
|
*/
|
|
272
272
|
outputHelp(cb?: (str: string) => string): void;
|
|
273
273
|
|
|
274
|
-
/** Output help information and exit.
|
|
275
|
-
|
|
274
|
+
/** Output help information and exit.
|
|
275
|
+
*
|
|
276
|
+
* @param {(str: string) => string} [cb]
|
|
277
|
+
*/
|
|
278
|
+
help(cb?: (str: string) => string): void;
|
|
276
279
|
}
|
|
277
280
|
|
|
278
281
|
}
|