commander 2.14.0 → 2.16.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,29 @@
1
1
 
2
+ 2.16.0 / 2018-06-29
3
+ ==================
4
+
5
+ * Remove Makefile and `test/run` (#821)
6
+ * Make 'npm test' run on Windows (#820)
7
+ * Add badge to display install size (#807)
8
+ * chore: cache node_modules (#814)
9
+ * chore: remove Node.js 4 (EOL), add Node.js 10 (#813)
10
+ * fixed typo in readme (#812)
11
+ * Fix types (#804)
12
+ * Update eslint to resolve vulnerabilities in lodash (#799)
13
+ * updated readme with custom event listeners. (#791)
14
+ * fix tests (#794)
15
+
16
+ 2.15.0 / 2018-03-07
17
+ ==================
18
+
19
+ * Update downloads badge to point to graph of downloads over time instead of duplicating link to npm
20
+ * Arguments description
21
+
22
+ 2.14.1 / 2018-02-07
23
+ ==================
24
+
25
+ * Fix typing of help function
26
+
2
27
  2.14.0 / 2018-02-05
3
28
  ==================
4
29
 
package/Readme.md CHANGED
@@ -3,7 +3,8 @@
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
+ [![Install Size](https://packagephobia.now.sh/badge?p=commander)](https://packagephobia.now.sh/result?p=commander)
7
8
  [![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
9
 
9
10
  The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).
@@ -232,7 +233,7 @@ program
232
233
  When `.command()` is invoked with a description argument, no `.action(callback)` should be called to handle sub-commands, otherwise there will be an error. This tells commander that you're going to use separate executables for sub-commands, much like `git(1)` and other popular tools.
233
234
  The commander will try to search the executables in the directory of the entry script (like `./examples/pm`) with the name `program-command`, like `pm-install`, `pm-search`.
234
235
 
235
- Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the option from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
236
+ Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the subcommand from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
236
237
 
237
238
  If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
238
239
 
@@ -356,6 +357,22 @@ function make_red(txt) {
356
357
  Output help information and exit immediately.
357
358
  Optional callback cb allows post-processing of help text before it is displayed.
358
359
 
360
+
361
+ ## Custom event listeners
362
+ You can execute custom actions by listening to command and option events.
363
+
364
+ ```js
365
+ program.on('option:verbose', function () {
366
+ process.env.VERBOSE = this.verbose;
367
+ });
368
+
369
+ // error on unknown commands
370
+ program.on('command:*', function () {
371
+ console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
372
+ process.exit(1);
373
+ });
374
+ ```
375
+
359
376
  ## Examples
360
377
 
361
378
  ```js
package/index.js CHANGED
@@ -43,9 +43,9 @@ exports.Option = Option;
43
43
 
44
44
  function Option(flags, description) {
45
45
  this.flags = flags;
46
- this.required = ~flags.indexOf('<');
47
- this.optional = ~flags.indexOf('[');
48
- this.bool = !~flags.indexOf('-no-');
46
+ this.required = flags.indexOf('<') >= 0;
47
+ this.optional = flags.indexOf('[') >= 0;
48
+ this.bool = flags.indexOf('-no-') === -1;
49
49
  flags = flags.split(/[ ,|]+/);
50
50
  if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift();
51
51
  this.long = flags.shift();
@@ -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
+ Command.prototype.description = function(str, argsDescription) {
877
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
 
@@ -938,6 +940,45 @@ Command.prototype.name = function(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,7 +1041,7 @@ 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) {
@@ -979,28 +1061,10 @@ 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 ? ' ' + 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
1068
  ' Commands:',
1005
1069
  '',
1006
1070
  commands.map(function(cmd) {
@@ -1025,6 +1089,17 @@ Command.prototype.helpInformation = function() {
1025
1089
  ' ' + this._description,
1026
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;
@@ -1042,7 +1117,6 @@ Command.prototype.helpInformation = function() {
1042
1117
  if (commandHelp) cmds = [commandHelp];
1043
1118
 
1044
1119
  var options = [
1045
- '',
1046
1120
  ' Options:',
1047
1121
  '',
1048
1122
  '' + this.optionHelp().replace(/^/gm, ' '),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commander",
3
- "version": "2.14.0",
3
+ "version": "2.16.0",
4
4
  "description": "the complete solution for node.js command-line programs",
5
5
  "keywords": [
6
6
  "commander",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "scripts": {
18
18
  "lint": "eslint index.js",
19
- "test": "make test && npm run test-typings",
19
+ "test": "node test/run.js && npm run test-typings",
20
20
  "test-typings": "node_modules/typescript/bin/tsc -p tsconfig.json"
21
21
  },
22
22
  "main": "index",
@@ -26,12 +26,12 @@
26
26
  ],
27
27
  "dependencies": {},
28
28
  "devDependencies": {
29
- "@types/node": "^7.0.52",
30
- "eslint": "^3.19.0",
29
+ "@types/node": "^7.0.66",
30
+ "eslint": "^4.19.1",
31
31
  "should": "^11.2.1",
32
32
  "sinon": "^2.4.1",
33
33
  "standard": "^10.0.3",
34
- "typescript": "^2.7.1"
34
+ "typescript": "^2.9.2"
35
35
  },
36
36
  "typings": "typings/index.d.ts"
37
37
  }
@@ -218,9 +218,9 @@ declare namespace local {
218
218
  /**
219
219
  * Return an object containing options as key-value pairs
220
220
  *
221
- * @returns {{[key: string]: string}}
221
+ * @returns {{[key: string]: any}}
222
222
  */
223
- opts(): { [key: string]: string };
223
+ opts(): { [key: string]: any };
224
224
 
225
225
  /**
226
226
  * Set the description to `str`.
@@ -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
- help(): void;
274
+ /** Output help information and exit.
275
+ *
276
+ * @param {(str: string) => string} [cb]
277
+ */
278
+ help(cb?: (str: string) => string): never;
276
279
  }
277
280
 
278
281
  }