commander 2.12.2 → 2.15.0

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 CHANGED
@@ -1,4 +1,34 @@
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
+
24
+ 2.13.0 / 2018-01-09
25
+ ==================
26
+
27
+ * Do not print default for --no-
28
+ * remove trailing spaces in command help
29
+ * Update CI's Node.js to LTS and latest version
30
+ * typedefs: Command and Option types added to commander namespace
31
+
2
32
  2.12.2 / 2017-11-28
3
33
  ==================
4
34
 
package/Readme.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  [![Build Status](https://api.travis-ci.org/tj/commander.js.svg?branch=master)](http://travis-ci.org/tj/commander.js)
5
5
  [![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander)
6
- [![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://www.npmjs.org/package/commander)
6
+ [![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://npmcharts.com/compare/commander?minimal=true)
7
7
  [![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](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
- 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.
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
- 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.
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( this.name() );
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 arg == this.short || arg == this.long;
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 (desc) {
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 && null == args[i]) {
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
- , option = new Option(flags, description)
376
- , oname = option.name()
377
- , name = option.attributeName();
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 != 'function') {
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 (false == option.bool || option.optional || option.required) {
394
+ if (!option.bool || option.optional || option.required) {
396
395
  // when --no-* we make sure default is true
397
- if (false == option.bool) defaultValue = true;
396
+ if (!option.bool) defaultValue = true;
398
397
  // preassign only if we have a default
399
- if (undefined !== defaultValue) {
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 (null !== val && fn) val = fn(val, undefined === self[name]
413
- ? defaultValue
414
- : self[name]);
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 ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) {
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 (null == val) {
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 (null !== val) {
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
- this._allowUnknownOption = arguments.length === 0 || arg;
444
- return this;
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] != "function") {
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 ('help' == args[0] && 1 == args.length) this.help();
515
+ if (args[0] === 'help' && args.length === 1) this.help();
517
516
 
518
517
  // <cmd> --help
519
- if ('help' == args[0]) {
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
- , link = fs.lstatSync(f).isSymbolicLink() ? fs.readlinkSync(f) : f;
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 ((proc.killed === false) && (proc.exitCode === null)){
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 == "ENOENT") {
579
+ if (err.code === 'ENOENT') {
582
580
  console.error('\n %s(1) does not exist, try --help\n', bin);
583
- } else if (err.code == "EACCES") {
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
- , arg
606
- , lastOpt
607
- , index;
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 && '-' == arg[0] && '-' != arg[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
- , len = argv.length
698
- , literal
699
- , option
700
- , arg;
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 ('--' == arg) {
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 (null == arg) return this.optionMissingArgument(option);
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 (null == arg || ('-' == arg[0] && '-' != arg)) {
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 && '-' == arg[0]) {
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 (argv[i+1] && '-' != argv[i+1][0]) {
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
- , len = this.options.length;
770
+ var result = {},
771
+ len = this.options.length;
774
772
 
775
- for (var i = 0 ; i < len; i++) {
773
+ for (var i = 0; i < len; i++) {
776
774
  var key = this.options[i].attributeName();
777
- result[key] = key === 'version' ? this._version : this[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 (0 == arguments.length) return this._version;
855
+ if (arguments.length === 0) return this._version;
858
856
  this._version = str;
859
857
  flags = flags || '-V, --version';
860
- this.option(flags, 'output the version number');
861
- this.on('option:version', function() {
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 (0 === arguments.length) return this._description;
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
- + (this.commands.length ? ' [command]' : '')
919
- + (this._args.length ? ' ' + args.join(' ') : '');
919
+ var usage = '[options]' +
920
+ (this.commands.length ? ' [command]' : '') +
921
+ (this._args.length ? ' ' + args.join(' ') : '');
920
922
 
921
- if (0 == arguments.length) return this._usage || usage;
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 (0 === arguments.length) return this._name;
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
- return this.options.reduce(function(max, option) {
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.largestOptionLength();
1044
+ var width = this.padWidth();
963
1045
 
964
1046
  // Append the help information
965
1047
  return this.options.map(function(option) {
966
- return pad(option.flags, width) + ' ' + option.description
967
- + (option.defaultValue !== undefined ? ' (default: ' + option.defaultValue + ')' : '');
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.commands.filter(function(cmd) {
983
- return !cmd._noHelp;
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
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
- , ' Commands:'
1005
- , ''
1006
- , commands.map(function(cmd) {
1068
+ ' Commands:',
1069
+ '',
1070
+ commands.map(function(cmd) {
1007
1071
  var desc = cmd[1] ? ' ' + cmd[1] : '';
1008
- return pad(cmd[0], width) + desc;
1009
- }).join('\n').replace(/^/gm, ' ')
1010
- , ''
1072
+ return (desc ? pad(cmd[0], width) : cmd[0]) + desc;
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] == '--help' || options[i] == '-h') {
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.12.2",
3
+ "version": "2.15.0",
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.48",
29
+ "@types/node": "^7.0.55",
30
+ "eslint": "^3.19.0",
29
31
  "should": "^11.2.1",
30
32
  "sinon": "^2.4.1",
31
- "typescript": "^2.6.2"
33
+ "standard": "^10.0.3",
34
+ "typescript": "^2.7.2"
32
35
  },
33
36
  "typings": "typings/index.d.ts"
34
37
  }
@@ -1,7 +1,11 @@
1
+ // Type definitions for commander 2.11
1
2
  // Project: https://github.com/visionmedia/commander.js
2
- // Definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>
3
+ // Definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>, Jules Randolph <https://github.com/sveinburne>
4
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
3
5
 
4
- declare class Option {
6
+ declare namespace local {
7
+
8
+ class Option {
5
9
  flags: string;
6
10
  required: boolean;
7
11
  optional: boolean;
@@ -17,9 +21,9 @@ declare class Option {
17
21
  * @param {string} [description]
18
22
  */
19
23
  constructor(flags: string, description?: string);
20
- }
24
+ }
21
25
 
22
- declare class Command extends NodeJS.EventEmitter {
26
+ class Command extends NodeJS.EventEmitter {
23
27
  [key: string]: any;
24
28
 
25
29
  args: string[];
@@ -121,6 +125,7 @@ declare class Command extends NodeJS.EventEmitter {
121
125
  * @returns {Command} for chaining
122
126
  */
123
127
  parseExpectedArgs(args: string[]): Command;
128
+
124
129
  /**
125
130
  * Register callback `fn` for the command.
126
131
  *
@@ -262,16 +267,25 @@ declare class Command extends NodeJS.EventEmitter {
262
267
  /**
263
268
  * Output help information for this command.
264
269
  *
265
- * @param {(str: string) => string} [cb]
270
+ * @param {(str: string) => string} [cb]
266
271
  */
267
272
  outputHelp(cb?: (str: string) => string): void;
268
273
 
269
- /** Output help information and exit. */
270
- help(): void;
274
+ /** Output help information and exit.
275
+ *
276
+ * @param {(str: string) => string} [cb]
277
+ */
278
+ help(cb?: (str: string) => string): void;
279
+ }
280
+
271
281
  }
272
282
 
273
283
  declare namespace commander {
274
284
 
285
+ type Command = local.Command
286
+
287
+ type Option = local.Option
288
+
275
289
  interface CommandOptions {
276
290
  noHelp?: boolean;
277
291
  isDefault?: boolean;
@@ -283,8 +297,8 @@ declare namespace commander {
283
297
  }
284
298
 
285
299
  interface CommanderStatic extends Command {
286
- Command: typeof Command;
287
- Option: typeof Option;
300
+ Command: typeof local.Command;
301
+ Option: typeof local.Option;
288
302
  CommandOptions: CommandOptions;
289
303
  ParseOptionsResult: ParseOptionsResult;
290
304
  }
@@ -292,4 +306,4 @@ declare namespace commander {
292
306
  }
293
307
 
294
308
  declare const commander: commander.CommanderStatic;
295
- export = commander;
309
+ export = commander;