commander 5.1.0 → 6.2.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 +85 -109
- package/Readme.md +118 -64
- package/index.js +194 -69
- package/package.json +13 -10
- package/typings/index.d.ts +28 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,65 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). (Format adopted after v3.0.0.)
|
|
7
7
|
|
|
8
8
|
<!-- markdownlint-disable MD024 -->
|
|
9
|
+
<!-- markdownlint-disable MD004 -->
|
|
10
|
+
|
|
11
|
+
## [6.2.1] (2020-12-13)
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- some tests failed if directory path included a space ([1390])
|
|
16
|
+
|
|
17
|
+
## [6.2.0] (2020-10-25)
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- added 'tsx' file extension for stand-alone executable subcommands ([#1368])
|
|
22
|
+
- documented second parameter to `.description()` to describe command arguments ([#1353])
|
|
23
|
+
- documentation of special cases with options taking varying numbers of option-arguments ([#1332])
|
|
24
|
+
- documentation for terminology ([#1361])
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- add missing TypeScript definition for `.addHelpCommand()' ([#1375])
|
|
29
|
+
- removed blank line after "Arguments:" in help, to match "Options:" and "Commands:" ([#1360])
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- update dependencies
|
|
34
|
+
|
|
35
|
+
## [6.1.0] (2020-08-28)
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- include URL to relevant section of README for error for potential conflict between Command properties and option values ([#1306])
|
|
40
|
+
- `.combineFlagAndOptionalValue(false)` to ease upgrade path from older versions of Commander ([#1326])
|
|
41
|
+
- allow disabling the built-in help option using `.helpOption(false)` ([#1325])
|
|
42
|
+
- allow just some arguments in `argumentDescription` to `.description()` ([#1323])
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- tidy async test and remove lint override ([#1312])
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- executable subcommand launching when script path not known ([#1322])
|
|
51
|
+
|
|
52
|
+
## [6.0.0] (2020-07-21)
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- add support for variadic options ([#1250])
|
|
57
|
+
- allow options to be added with just a short flag ([#1256])
|
|
58
|
+
- *Breaking* the option property has same case as flag. e.g. flag `-n` accessed as `opts().n` (previously uppercase)
|
|
59
|
+
- *Breaking* throw an error if there might be a clash between option name and a Command property, with advice on how to resolve ([#1275])
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
- Options which contain -no- in the middle of the option flag should not be treated as negatable. ([#1301])
|
|
64
|
+
|
|
65
|
+
## [6.0.0-0] (2020-06-20)
|
|
66
|
+
|
|
67
|
+
(Released in 6.0.0)
|
|
9
68
|
|
|
10
69
|
## [5.1.0] (2020-04-25)
|
|
11
70
|
|
|
@@ -96,6 +155,9 @@ If you use `program.args` or more complicated tests to detect a missing subcomma
|
|
|
96
155
|
|
|
97
156
|
If you use `.command('*')` to add a default command, you may be be able to switch to `isDefault:true` with a named command.
|
|
98
157
|
|
|
158
|
+
If you want to continue combining short options with optional values as though they were boolean flags, set `combineFlagAndOptionalValue(false)`
|
|
159
|
+
to expand `-fb` to `-f -b` rather than `-f b`.
|
|
160
|
+
|
|
99
161
|
## [5.0.0-4] (2020-03-03)
|
|
100
162
|
|
|
101
163
|
(Released in 5.0.0)
|
|
@@ -198,95 +260,9 @@ if (program.rawArgs.length < 3) ...
|
|
|
198
260
|
|
|
199
261
|
(Released in 4.0.0)
|
|
200
262
|
|
|
201
|
-
## [2.20.1] (2019-09-29)
|
|
202
|
-
|
|
203
|
-
### Fixed
|
|
204
|
-
|
|
205
|
-
* Improve tracking of executable subcommands.
|
|
206
|
-
|
|
207
|
-
### Changed
|
|
208
|
-
|
|
209
|
-
* update development dependencies
|
|
210
|
-
|
|
211
|
-
## [3.0.2] (2019-09-27)
|
|
212
|
-
|
|
213
|
-
### Fixed
|
|
214
|
-
|
|
215
|
-
* Improve tracking of executable subcommands.
|
|
216
|
-
|
|
217
|
-
### Changed
|
|
218
|
-
|
|
219
|
-
* update development dependencies
|
|
220
|
-
|
|
221
|
-
## [3.0.1] (2019-08-30)
|
|
222
|
-
|
|
223
|
-
### Added
|
|
224
|
-
|
|
225
|
-
* .name and .usage to README ([#1010])
|
|
226
|
-
* Table of Contents to README ([#1010])
|
|
227
|
-
* TypeScript definition for `executableFile` in CommandOptions ([#1028])
|
|
228
|
-
|
|
229
|
-
### Changed
|
|
230
|
-
|
|
231
|
-
* consistently use `const` rather than `var` in README ([#1026])
|
|
232
|
-
|
|
233
|
-
### Fixed
|
|
234
|
-
|
|
235
|
-
* help for sub commands with custom executableFile ([#1018])
|
|
236
|
-
|
|
237
|
-
## [3.0.0] / 2019-08-08
|
|
238
|
-
|
|
239
|
-
* Add option to specify executable file name ([#999])
|
|
240
|
-
* e.g. `.command('clone', 'clone description', { executableFile: 'myClone' })`
|
|
241
|
-
* Change docs for `.command` to contrast action handler vs git-style executable. ([#938] [#990])
|
|
242
|
-
* **Breaking** Change TypeScript to use overloaded function for `.command`. ([#938] [#990])
|
|
243
|
-
* Change to use straight quotes around strings in error messages (like 'this' instead of `this') ([#915])
|
|
244
|
-
* Add TypeScript "reference types" for node ([#974])
|
|
245
|
-
* Add support for hyphen as an option argument in subcommands ([#697])
|
|
246
|
-
* Add support for a short option flag and its value to be concatenated for action handler subcommands ([#599])
|
|
247
|
-
* e.g. `-p 80` can also be supplied as `-p80`
|
|
248
|
-
* Add executable arguments to spawn in win32, for git-style executables ([#611])
|
|
249
|
-
* e.g. `node --harmony myCommand.js clone`
|
|
250
|
-
* Add parent command as prefix of subcommand in help ([#980])
|
|
251
|
-
* Add optional custom description to `.version` ([#963])
|
|
252
|
-
* e.g. `program.version('0.0.1', '-v, --vers', 'output the current version')`
|
|
253
|
-
* Add `.helpOption(flags, description)` routine to customise help flags and description ([#963])
|
|
254
|
-
* e.g. `.helpOption('-e, --HELP', 'read more information')`
|
|
255
|
-
* Fix behavior of --no-* options ([#795])
|
|
256
|
-
* can now define both `--foo` and `--no-foo`
|
|
257
|
-
* **Breaking** custom event listeners: `--no-foo` on cli now emits `option:no-foo` (previously `option:foo`)
|
|
258
|
-
* **Breaking** default value: defining `--no-foo` after defining `--foo` leaves the default value unchanged (previously set it to false)
|
|
259
|
-
* allow boolean default value, such as from environment ([#987])
|
|
260
|
-
* Increment inspector port for spawned subcommands ([#991])
|
|
261
|
-
* e.g. `node --inspect myCommand.js clone`
|
|
262
|
-
|
|
263
|
-
### Migration Tips
|
|
264
|
-
|
|
265
|
-
The custom event for a negated option like `--no-foo` is `option:no-foo` (previously `option:foo`).
|
|
266
|
-
|
|
267
|
-
```js
|
|
268
|
-
program
|
|
269
|
-
.option('--no-foo')
|
|
270
|
-
.on('option:no-foo', () => {
|
|
271
|
-
console.log('removing foo');
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
When using TypeScript, adding a command does not allow an explicit `undefined` for an unwanted executable description (e.g
|
|
276
|
-
for a command with an action handler).
|
|
277
|
-
|
|
278
|
-
```js
|
|
279
|
-
program
|
|
280
|
-
.command('action1', undefined, { noHelp: true }) // No longer valid
|
|
281
|
-
.command('action2', { noHelp: true }) // Correct
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
## 3.0.0-0 Prerelease / 2019-07-28
|
|
285
|
-
|
|
286
|
-
(Released as 3.0.0)
|
|
287
|
-
|
|
288
263
|
## Older versions
|
|
289
264
|
|
|
265
|
+
* [3.x](./changelogs/CHANGELOG-3.md)
|
|
290
266
|
* [2.x](./changelogs/CHANGELOG-2.md)
|
|
291
267
|
* [1.x](./changelogs/CHANGELOG-1.md)
|
|
292
268
|
* [0.x](./changelogs/CHANGELOG-0.md)
|
|
@@ -296,34 +272,16 @@ program
|
|
|
296
272
|
[#508]: https://github.com/tj/commander.js/issues/508
|
|
297
273
|
[#512]: https://github.com/tj/commander.js/issues/512
|
|
298
274
|
[#531]: https://github.com/tj/commander.js/issues/531
|
|
299
|
-
[#599]: https://github.com/tj/commander.js/issues/599
|
|
300
|
-
[#611]: https://github.com/tj/commander.js/issues/611
|
|
301
275
|
[#645]: https://github.com/tj/commander.js/issues/645
|
|
302
|
-
[#697]: https://github.com/tj/commander.js/issues/697
|
|
303
276
|
[#742]: https://github.com/tj/commander.js/issues/742
|
|
304
277
|
[#764]: https://github.com/tj/commander.js/issues/764
|
|
305
|
-
[#795]: https://github.com/tj/commander.js/issues/795
|
|
306
278
|
[#802]: https://github.com/tj/commander.js/issues/802
|
|
307
279
|
[#806]: https://github.com/tj/commander.js/issues/806
|
|
308
280
|
[#809]: https://github.com/tj/commander.js/issues/809
|
|
309
|
-
[#915]: https://github.com/tj/commander.js/issues/915
|
|
310
|
-
[#938]: https://github.com/tj/commander.js/issues/938
|
|
311
281
|
[#948]: https://github.com/tj/commander.js/issues/948
|
|
312
282
|
[#962]: https://github.com/tj/commander.js/issues/962
|
|
313
|
-
[#963]: https://github.com/tj/commander.js/issues/963
|
|
314
|
-
[#974]: https://github.com/tj/commander.js/issues/974
|
|
315
|
-
[#980]: https://github.com/tj/commander.js/issues/980
|
|
316
|
-
[#987]: https://github.com/tj/commander.js/issues/987
|
|
317
|
-
[#990]: https://github.com/tj/commander.js/issues/990
|
|
318
|
-
[#991]: https://github.com/tj/commander.js/issues/991
|
|
319
|
-
[#993]: https://github.com/tj/commander.js/issues/993
|
|
320
283
|
[#995]: https://github.com/tj/commander.js/issues/995
|
|
321
|
-
[#999]: https://github.com/tj/commander.js/issues/999
|
|
322
|
-
[#1010]: https://github.com/tj/commander.js/pull/1010
|
|
323
|
-
[#1018]: https://github.com/tj/commander.js/pull/1018
|
|
324
|
-
[#1026]: https://github.com/tj/commander.js/pull/1026
|
|
325
284
|
[#1027]: https://github.com/tj/commander.js/pull/1027
|
|
326
|
-
[#1028]: https://github.com/tj/commander.js/pull/1028
|
|
327
285
|
[#1032]: https://github.com/tj/commander.js/issues/1032
|
|
328
286
|
[#1035]: https://github.com/tj/commander.js/pull/1035
|
|
329
287
|
[#1040]: https://github.com/tj/commander.js/pull/1040
|
|
@@ -364,8 +322,30 @@ program
|
|
|
364
322
|
[#1236]: https://github.com/tj/commander.js/pull/1236
|
|
365
323
|
[#1247]: https://github.com/tj/commander.js/pull/1247
|
|
366
324
|
[#1248]: https://github.com/tj/commander.js/pull/1248
|
|
325
|
+
[#1250]: https://github.com/tj/commander.js/pull/1250
|
|
326
|
+
[#1256]: https://github.com/tj/commander.js/pull/1256
|
|
327
|
+
[#1275]: https://github.com/tj/commander.js/pull/1275
|
|
328
|
+
[#1301]: https://github.com/tj/commander.js/issues/1301
|
|
329
|
+
[#1306]: https://github.com/tj/commander.js/pull/1306
|
|
330
|
+
[#1312]: https://github.com/tj/commander.js/pull/1312
|
|
331
|
+
[#1322]: https://github.com/tj/commander.js/pull/1322
|
|
332
|
+
[#1323]: https://github.com/tj/commander.js/pull/1323
|
|
333
|
+
[#1325]: https://github.com/tj/commander.js/pull/1325
|
|
334
|
+
[#1326]: https://github.com/tj/commander.js/pull/1326
|
|
335
|
+
[#1332]: https://github.com/tj/commander.js/pull/1332
|
|
336
|
+
[#1353]: https://github.com/tj/commander.js/pull/1353
|
|
337
|
+
[#1360]: https://github.com/tj/commander.js/pull/1360
|
|
338
|
+
[#1361]: https://github.com/tj/commander.js/pull/1361
|
|
339
|
+
[#1368]: https://github.com/tj/commander.js/pull/1368
|
|
340
|
+
[#1375]: https://github.com/tj/commander.js/pull/1375
|
|
341
|
+
[#1390]: https://github.com/tj/commander.js/pull/1390
|
|
367
342
|
|
|
368
343
|
[Unreleased]: https://github.com/tj/commander.js/compare/master...develop
|
|
344
|
+
[6.2.1]: https://github.com/tj/commander.js/compare/v6.2.0..v6.2.1
|
|
345
|
+
[6.2.0]: https://github.com/tj/commander.js/compare/v6.1.0..v6.2.0
|
|
346
|
+
[6.1.0]: https://github.com/tj/commander.js/compare/v6.0.0..v6.1.0
|
|
347
|
+
[6.0.0]: https://github.com/tj/commander.js/compare/v5.1.0..v6.0.0
|
|
348
|
+
[6.0.0-0]: https://github.com/tj/commander.js/compare/v5.1.0..v6.0.0-0
|
|
369
349
|
[5.1.0]: https://github.com/tj/commander.js/compare/v5.0.0..v5.1.0
|
|
370
350
|
[5.0.0]: https://github.com/tj/commander.js/compare/v4.1.1..v5.0.0
|
|
371
351
|
[5.0.0-4]: https://github.com/tj/commander.js/compare/v5.0.0-3..v5.0.0-4
|
|
@@ -379,7 +359,3 @@ program
|
|
|
379
359
|
[4.0.0]: https://github.com/tj/commander.js/compare/v3.0.2..v4.0.0
|
|
380
360
|
[4.0.0-1]: https://github.com/tj/commander.js/compare/v4.0.0-0..v4.0.0-1
|
|
381
361
|
[4.0.0-0]: https://github.com/tj/commander.js/compare/v3.0.2...v4.0.0-0
|
|
382
|
-
[3.0.2]: https://github.com/tj/commander.js/compare/v3.0.1...v3.0.2
|
|
383
|
-
[3.0.1]: https://github.com/tj/commander.js/compare/v3.0.0...v3.0.1
|
|
384
|
-
[3.0.0]: https://github.com/tj/commander.js/compare/v2.20.1...v3.0.0
|
|
385
|
-
[2.20.1]: https://github.com/tj/commander.js/compare/v2.20.0...v2.20.1
|
package/Readme.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://npmcharts.com/compare/commander?minimal=true)
|
|
6
6
|
[](https://packagephobia.now.sh/result?p=commander)
|
|
7
7
|
|
|
8
|
-
The complete solution for [node.js](http://nodejs.org) command-line interfaces
|
|
8
|
+
The complete solution for [node.js](http://nodejs.org) command-line interfaces.
|
|
9
9
|
|
|
10
10
|
Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
|
|
11
11
|
|
|
@@ -15,9 +15,10 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
|
|
|
15
15
|
- [Options](#options)
|
|
16
16
|
- [Common option types, boolean and value](#common-option-types-boolean-and-value)
|
|
17
17
|
- [Default option value](#default-option-value)
|
|
18
|
-
- [Other option types, negatable boolean and
|
|
18
|
+
- [Other option types, negatable boolean and boolean|value](#other-option-types-negatable-boolean-and-booleanvalue)
|
|
19
19
|
- [Custom option processing](#custom-option-processing)
|
|
20
20
|
- [Required option](#required-option)
|
|
21
|
+
- [Variadic option](#variadic-option)
|
|
21
22
|
- [Version option](#version-option)
|
|
22
23
|
- [Commands](#commands)
|
|
23
24
|
- [Specify the argument syntax](#specify-the-argument-syntax)
|
|
@@ -37,14 +38,16 @@ Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
|
|
|
37
38
|
- [Avoiding option name clashes](#avoiding-option-name-clashes)
|
|
38
39
|
- [TypeScript](#typescript)
|
|
39
40
|
- [createCommand()](#createcommand)
|
|
41
|
+
- [Import into ECMAScript Module](#import-into-ecmascript-module)
|
|
40
42
|
- [Node options such as `--harmony`](#node-options-such-as---harmony)
|
|
41
43
|
- [Debugging stand-alone executable subcommands](#debugging-stand-alone-executable-subcommands)
|
|
42
44
|
- [Override exit handling](#override-exit-handling)
|
|
43
45
|
- [Examples](#examples)
|
|
44
|
-
- [License](#license)
|
|
45
46
|
- [Support](#support)
|
|
46
47
|
- [Commander for enterprise](#commander-for-enterprise)
|
|
47
48
|
|
|
49
|
+
For information about terms used in this document see: [terminology](./docs/terminology.md)
|
|
50
|
+
|
|
48
51
|
## Installation
|
|
49
52
|
|
|
50
53
|
```bash
|
|
@@ -63,11 +66,11 @@ program.version('0.0.1');
|
|
|
63
66
|
|
|
64
67
|
For larger programs which may use commander in multiple ways, including unit testing, it is better to create a local Command object to use.
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
```js
|
|
70
|
+
const { Command } = require('commander');
|
|
71
|
+
const program = new Command();
|
|
72
|
+
program.version('0.0.1');
|
|
73
|
+
```
|
|
71
74
|
|
|
72
75
|
## Options
|
|
73
76
|
|
|
@@ -75,22 +78,21 @@ Options are defined with the `.option()` method, also serving as documentation f
|
|
|
75
78
|
|
|
76
79
|
The options can be accessed as properties on the Command object. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. See also optional new behaviour to [avoid name clashes](#avoiding-option-name-clashes).
|
|
77
80
|
|
|
78
|
-
Multiple short flags may optionally be combined in a single argument following the dash: boolean flags,
|
|
81
|
+
Multiple short flags may optionally be combined in a single argument following the dash: boolean flags, followed by a single option taking a value (possibly followed by the value).
|
|
79
82
|
For example `-a -b -p 80` may be written as `-ab -p80` or even `-abp80`.
|
|
80
83
|
|
|
81
84
|
You can use `--` to indicate the end of the options, and any remaining arguments will be used without being interpreted.
|
|
82
|
-
This is particularly useful for passing options through to another
|
|
83
|
-
command, like: `do -- git --version`.
|
|
84
85
|
|
|
85
|
-
Options on the command line are not positional, and can be specified before or after other
|
|
86
|
+
Options on the command line are not positional, and can be specified before or after other arguments.
|
|
86
87
|
|
|
87
88
|
### Common option types, boolean and value
|
|
88
89
|
|
|
89
|
-
The two most used option types are a boolean
|
|
90
|
+
The two most used option types are a boolean option, and an option which takes its value
|
|
91
|
+
from the following argument (declared with angle brackets like `--expect <value>`). Both are `undefined` unless specified on command line.
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
const { program } = require('commander');
|
|
93
|
+
Example file: [options-common.js](./examples/options-common.js)
|
|
93
94
|
|
|
95
|
+
```js
|
|
94
96
|
program
|
|
95
97
|
.option('-d, --debug', 'output extra debugging')
|
|
96
98
|
.option('-s, --small', 'small pizza size')
|
|
@@ -126,9 +128,9 @@ pizza details:
|
|
|
126
128
|
|
|
127
129
|
You can specify a default value for an option which takes a value.
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
const { program } = require('commander');
|
|
131
|
+
Example file: [options-defaults.js](./examples/options-defaults.js)
|
|
131
132
|
|
|
133
|
+
```js
|
|
132
134
|
program
|
|
133
135
|
.option('-c, --cheese <type>', 'add the specified type of cheese', 'blue');
|
|
134
136
|
|
|
@@ -144,17 +146,17 @@ $ pizza-options --cheese stilton
|
|
|
144
146
|
cheese: stilton
|
|
145
147
|
```
|
|
146
148
|
|
|
147
|
-
### Other option types, negatable boolean and
|
|
149
|
+
### Other option types, negatable boolean and boolean|value
|
|
148
150
|
|
|
149
|
-
You can
|
|
151
|
+
You can define a boolean option long name with a leading `no-` to set the option value to false when used.
|
|
150
152
|
Defined alone this also makes the option true by default.
|
|
151
153
|
|
|
152
154
|
If you define `--foo` first, adding `--no-foo` does not change the default value from what it would
|
|
153
|
-
otherwise be. You can specify a default boolean value for a boolean
|
|
155
|
+
otherwise be. You can specify a default boolean value for a boolean option and it can be overridden on command line.
|
|
154
156
|
|
|
155
|
-
|
|
156
|
-
const { program } = require('commander');
|
|
157
|
+
Example file: [options-negatable.js](./examples/options-negatable.js)
|
|
157
158
|
|
|
159
|
+
```js
|
|
158
160
|
program
|
|
159
161
|
.option('--no-sauce', 'Remove sauce')
|
|
160
162
|
.option('--cheese <flavour>', 'cheese flavour', 'mozzarella')
|
|
@@ -177,11 +179,12 @@ $ pizza-options --no-sauce --no-cheese
|
|
|
177
179
|
You ordered a pizza with no sauce and no cheese
|
|
178
180
|
```
|
|
179
181
|
|
|
180
|
-
You can specify an option which
|
|
182
|
+
You can specify an option which may be used as a boolean option but may optionally take an option-argument
|
|
183
|
+
(declared with square brackets like `--optional [value]`).
|
|
181
184
|
|
|
182
|
-
|
|
183
|
-
const { program } = require('commander');
|
|
185
|
+
Example file: [options-boolean-or-value.js](./examples/options-boolean-or-value.js)
|
|
184
186
|
|
|
187
|
+
```js
|
|
185
188
|
program
|
|
186
189
|
.option('-c, --cheese [type]', 'Add cheese with optional type');
|
|
187
190
|
|
|
@@ -201,18 +204,20 @@ $ pizza-options --cheese mozzarella
|
|
|
201
204
|
add cheese type mozzarella
|
|
202
205
|
```
|
|
203
206
|
|
|
207
|
+
For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-taking-varying-arguments.md).
|
|
208
|
+
|
|
204
209
|
### Custom option processing
|
|
205
210
|
|
|
206
|
-
You may specify a function to do custom processing of option
|
|
207
|
-
previous value for the option. It returns the new value for the option.
|
|
211
|
+
You may specify a function to do custom processing of option-arguments. The callback function receives two parameters,
|
|
212
|
+
the user specified option-argument and the previous value for the option. It returns the new value for the option.
|
|
208
213
|
|
|
209
|
-
This allows you to coerce the option
|
|
214
|
+
This allows you to coerce the option-argument to the desired type, or accumulate values, or do entirely custom processing.
|
|
210
215
|
|
|
211
|
-
You can optionally specify the default/starting value for the option after the function.
|
|
216
|
+
You can optionally specify the default/starting value for the option after the function parameter.
|
|
212
217
|
|
|
213
|
-
|
|
214
|
-
const { program } = require('commander');
|
|
218
|
+
Example file: [options-custom-processing.js](./examples/options-custom-processing.js)
|
|
215
219
|
|
|
220
|
+
```js
|
|
216
221
|
function myParseInt(value, dummyPrevious) {
|
|
217
222
|
// parseInt takes a string and an optional radix
|
|
218
223
|
return parseInt(value);
|
|
@@ -264,9 +269,9 @@ $ custom --list x,y,z
|
|
|
264
269
|
|
|
265
270
|
You may specify a required (mandatory) option using `.requiredOption`. The option must have a value after parsing, usually specified on the command line, or perhaps from a default value (say from environment). The method is otherwise the same as `.option` in format, taking flags and description, and optional default value or custom processing.
|
|
266
271
|
|
|
267
|
-
|
|
268
|
-
const { program } = require('commander');
|
|
272
|
+
Example file: [options-required.js](./examples/options-required.js)
|
|
269
273
|
|
|
274
|
+
```js
|
|
270
275
|
program
|
|
271
276
|
.requiredOption('-c, --cheese <type>', 'pizza must have cheese');
|
|
272
277
|
|
|
@@ -278,6 +283,40 @@ $ pizza
|
|
|
278
283
|
error: required option '-c, --cheese <type>' not specified
|
|
279
284
|
```
|
|
280
285
|
|
|
286
|
+
### Variadic option
|
|
287
|
+
|
|
288
|
+
You may make an option variadic by appending `...` to the value placeholder when declaring the option. On the command line you
|
|
289
|
+
can then specify multiple option-arguments, and the parsed option value will be an array. The extra arguments
|
|
290
|
+
are read until the first argument starting with a dash. The special argument `--` stops option processing entirely. If a value
|
|
291
|
+
is specified in the same argument as the option then no further values are read.
|
|
292
|
+
|
|
293
|
+
Example file: [options-variadic.js](./examples/options-variadic.js)
|
|
294
|
+
|
|
295
|
+
```js
|
|
296
|
+
program
|
|
297
|
+
.option('-n, --number <numbers...>', 'specify numbers')
|
|
298
|
+
.option('-l, --letter [letters...]', 'specify letters');
|
|
299
|
+
|
|
300
|
+
program.parse();
|
|
301
|
+
|
|
302
|
+
console.log('Options: ', program.opts());
|
|
303
|
+
console.log('Remaining arguments: ', program.args);
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
$ collect -n 1 2 3 --letter a b c
|
|
308
|
+
Options: { number: [ '1', '2', '3' ], letter: [ 'a', 'b', 'c' ] }
|
|
309
|
+
Remaining arguments: []
|
|
310
|
+
$ collect --letter=A -n80 operand
|
|
311
|
+
Options: { number: [ '80' ], letter: [ 'A' ] }
|
|
312
|
+
Remaining arguments: [ 'operand' ]
|
|
313
|
+
$ collect --letter -n 1 -n 2 3 -- operand
|
|
314
|
+
Options: { number: [ '1', '2', '3' ], letter: true }
|
|
315
|
+
Remaining arguments: [ 'operand' ]
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-taking-varying-arguments.md).
|
|
319
|
+
|
|
281
320
|
### Version option
|
|
282
321
|
|
|
283
322
|
The optional `version` method adds handling for displaying the command version. The default option flags are `-V` and `--version`, and when present the command prints the version number and exits.
|
|
@@ -292,7 +331,7 @@ $ ./examples/pizza -V
|
|
|
292
331
|
```
|
|
293
332
|
|
|
294
333
|
You may change the flags and description by passing additional parameters to the `version` method, using
|
|
295
|
-
the same syntax for flags as the `option` method.
|
|
334
|
+
the same syntax for flags as the `option` method.
|
|
296
335
|
|
|
297
336
|
```js
|
|
298
337
|
program.version('0.0.1', '-v, --vers', 'output the current version');
|
|
@@ -302,7 +341,7 @@ program.version('0.0.1', '-v, --vers', 'output the current version');
|
|
|
302
341
|
|
|
303
342
|
You can specify (sub)commands using `.command()` or `.addCommand()`. There are two ways these can be implemented: using an action handler attached to the command, or as a stand-alone executable file (described in more detail later). The subcommands may be nested ([example](./examples/nestedCommands.js)).
|
|
304
343
|
|
|
305
|
-
In the first parameter to `.command()` you specify the command name and any command
|
|
344
|
+
In the first parameter to `.command()` you specify the command name and any command-arguments. The arguments may be `<required>` or `[optional]`, and the last argument may also be `variadic...`.
|
|
306
345
|
|
|
307
346
|
You can use `.addCommand()` to add an already configured subcommand to the program.
|
|
308
347
|
|
|
@@ -330,31 +369,33 @@ program
|
|
|
330
369
|
.addCommand(build.makeBuildCommand());
|
|
331
370
|
```
|
|
332
371
|
|
|
333
|
-
Configuration options can be passed with the call to `.command()` and `.addCommand()`. Specifying `
|
|
372
|
+
Configuration options can be passed with the call to `.command()` and `.addCommand()`. Specifying `hidden: true` will
|
|
373
|
+
remove the command from the generated help output. Specifying `isDefault: true` will run the subcommand if no other
|
|
374
|
+
subcommand is specified ([example](./examples/defaultCommand.js)).
|
|
334
375
|
|
|
335
376
|
### Specify the argument syntax
|
|
336
377
|
|
|
337
|
-
You use `.arguments` to specify the arguments for the top-level command, and for subcommands they are usually
|
|
378
|
+
You use `.arguments` to specify the expected command-arguments for the top-level command, and for subcommands they are usually
|
|
379
|
+
included in the `.command` call. Angled brackets (e.g. `<required>`) indicate required command-arguments.
|
|
380
|
+
Square brackets (e.g. `[optional]`) indicate optional command-arguments.
|
|
381
|
+
You can optionally describe the arguments in the help by supplying a hash as second parameter to `.description()`.
|
|
338
382
|
|
|
339
|
-
|
|
340
|
-
const { program } = require('commander');
|
|
383
|
+
Example file: [env](./examples/env)
|
|
341
384
|
|
|
385
|
+
```js
|
|
342
386
|
program
|
|
343
387
|
.version('0.1.0')
|
|
344
388
|
.arguments('<cmd> [env]')
|
|
389
|
+
.description('test command', {
|
|
390
|
+
cmd: 'command to run',
|
|
391
|
+
env: 'environment to run test in'
|
|
392
|
+
})
|
|
345
393
|
.action(function (cmd, env) {
|
|
346
|
-
|
|
347
|
-
|
|
394
|
+
console.log('command:', cmd);
|
|
395
|
+
console.log('environment:', env || 'no environment given');
|
|
348
396
|
});
|
|
349
397
|
|
|
350
398
|
program.parse(process.argv);
|
|
351
|
-
|
|
352
|
-
if (typeof cmdValue === 'undefined') {
|
|
353
|
-
console.error('no command given!');
|
|
354
|
-
process.exit(1);
|
|
355
|
-
}
|
|
356
|
-
console.log('command:', cmdValue);
|
|
357
|
-
console.log('environment:', envValue || "no environment given");
|
|
358
399
|
```
|
|
359
400
|
|
|
360
401
|
The last argument of a command can be variadic, and only the last argument. To make an argument variadic you
|
|
@@ -422,17 +463,17 @@ You can specify a custom name with the `executableFile` configuration option.
|
|
|
422
463
|
|
|
423
464
|
You handle the options for an executable (sub)command in the executable, and don't declare them at the top-level.
|
|
424
465
|
|
|
425
|
-
|
|
426
|
-
// file: ./examples/pm
|
|
427
|
-
const { program } = require('commander');
|
|
466
|
+
Example file: [pm](./examples/pm)
|
|
428
467
|
|
|
468
|
+
```js
|
|
429
469
|
program
|
|
430
470
|
.version('0.1.0')
|
|
431
471
|
.command('install [name]', 'install one or more packages')
|
|
432
472
|
.command('search [query]', 'search with optional query')
|
|
433
|
-
.command('update', 'update installed packages', {executableFile: 'myUpdateSubCommand'})
|
|
434
|
-
.command('list', 'list packages installed', {isDefault: true})
|
|
435
|
-
|
|
473
|
+
.command('update', 'update installed packages', { executableFile: 'myUpdateSubCommand' })
|
|
474
|
+
.command('list', 'list packages installed', { isDefault: true });
|
|
475
|
+
|
|
476
|
+
program.parse(process.argv);
|
|
436
477
|
```
|
|
437
478
|
|
|
438
479
|
If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
|
|
@@ -440,7 +481,9 @@ If the program is designed to be installed globally, make sure the executables h
|
|
|
440
481
|
## Automated help
|
|
441
482
|
|
|
442
483
|
The help information is auto-generated based on the information commander already knows about your program. The default
|
|
443
|
-
help option is `-h,--help`.
|
|
484
|
+
help option is `-h,--help`.
|
|
485
|
+
|
|
486
|
+
Example file: [pizza](./examples/pizza)
|
|
444
487
|
|
|
445
488
|
```bash
|
|
446
489
|
$ node ./examples/pizza --help
|
|
@@ -469,7 +512,9 @@ shell spawn --help
|
|
|
469
512
|
|
|
470
513
|
### Custom help
|
|
471
514
|
|
|
472
|
-
You can display extra information by listening for "--help".
|
|
515
|
+
You can display extra information by listening for "--help".
|
|
516
|
+
|
|
517
|
+
Example file: [custom-help](./examples/custom-help)
|
|
473
518
|
|
|
474
519
|
```js
|
|
475
520
|
program
|
|
@@ -529,7 +574,7 @@ from `--help` listeners.)
|
|
|
529
574
|
|
|
530
575
|
### .helpOption(flags, description)
|
|
531
576
|
|
|
532
|
-
Override the default help flags and description.
|
|
577
|
+
Override the default help flags and description. Pass false to disable the built-in help option.
|
|
533
578
|
|
|
534
579
|
```js
|
|
535
580
|
program
|
|
@@ -597,7 +642,7 @@ There are two new routines to change the behaviour, and the default behaviour ma
|
|
|
597
642
|
- `passCommandToAction`: whether to pass command to action handler,
|
|
598
643
|
or just the options (specify false)
|
|
599
644
|
|
|
600
|
-
|
|
645
|
+
Example file: [storeOptionsAsProperties-action.js](./examples/storeOptionsAsProperties-action.js)
|
|
601
646
|
|
|
602
647
|
```js
|
|
603
648
|
program
|
|
@@ -644,6 +689,17 @@ const program = createCommand();
|
|
|
644
689
|
when creating subcommands using `.command()`, and you may override it to
|
|
645
690
|
customise the new subcommand (examples using [subclass](./examples/custom-command-class.js) and [function](./examples/custom-command-function.js)).
|
|
646
691
|
|
|
692
|
+
### Import into ECMAScript Module
|
|
693
|
+
|
|
694
|
+
Commander is currently a CommonJS package, and the default export can be imported into an ES Module:
|
|
695
|
+
|
|
696
|
+
```js
|
|
697
|
+
// index.mjs
|
|
698
|
+
import commander from 'commander';
|
|
699
|
+
const program = commander.program;
|
|
700
|
+
const newCommand = new commander.Command();
|
|
701
|
+
```
|
|
702
|
+
|
|
647
703
|
### Node options such as `--harmony`
|
|
648
704
|
|
|
649
705
|
You can enable `--harmony` option in two ways:
|
|
@@ -668,7 +724,7 @@ this behaviour and optionally supply a callback. The default override throws a `
|
|
|
668
724
|
The override callback is passed a `CommanderError` with properties `exitCode` number, `code` string, and `message`. The default override behaviour is to throw the error, except for async handling of executable subcommand completion which carries on. The normal display of error messages or version or help
|
|
669
725
|
is not affected by the override which is called after the display.
|
|
670
726
|
|
|
671
|
-
```
|
|
727
|
+
```js
|
|
672
728
|
program.exitOverride();
|
|
673
729
|
|
|
674
730
|
try {
|
|
@@ -680,6 +736,8 @@ try {
|
|
|
680
736
|
|
|
681
737
|
## Examples
|
|
682
738
|
|
|
739
|
+
Example file: [deploy](./examples/deploy)
|
|
740
|
+
|
|
683
741
|
```js
|
|
684
742
|
const { program } = require('commander');
|
|
685
743
|
|
|
@@ -719,13 +777,9 @@ program.parse(process.argv);
|
|
|
719
777
|
|
|
720
778
|
More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
|
|
721
779
|
|
|
722
|
-
## License
|
|
723
|
-
|
|
724
|
-
[MIT](https://github.com/tj/commander.js/blob/master/LICENSE)
|
|
725
|
-
|
|
726
780
|
## Support
|
|
727
781
|
|
|
728
|
-
Commander
|
|
782
|
+
The current version of Commander is fully supported on Long Term Support versions of Node, and is likely to work with Node 6 but not tested.
|
|
729
783
|
(For versions of Node below Node 6, use Commander 3.x or 2.x.)
|
|
730
784
|
|
|
731
785
|
The main forum for free and community support is the project [Issues](https://github.com/tj/commander.js/issues) on GitHub.
|
package/index.js
CHANGED
|
@@ -20,13 +20,18 @@ class Option {
|
|
|
20
20
|
|
|
21
21
|
constructor(flags, description) {
|
|
22
22
|
this.flags = flags;
|
|
23
|
-
this.required = flags.
|
|
24
|
-
this.optional = flags.
|
|
23
|
+
this.required = flags.includes('<'); // A value must be supplied when the option is specified.
|
|
24
|
+
this.optional = flags.includes('['); // A value is optional when the option is specified.
|
|
25
|
+
// variadic test ignores <value,...> et al which might be used to describe custom splitting of single argument
|
|
26
|
+
this.variadic = /\w\.\.\.[>\]]$/.test(flags); // The option can take multiple values.
|
|
25
27
|
this.mandatory = false; // The option must have a value after parsing, which usually means it must be specified on command line.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.
|
|
28
|
+
const optionFlags = _parseOptionFlags(flags);
|
|
29
|
+
this.short = optionFlags.shortFlag;
|
|
30
|
+
this.long = optionFlags.longFlag;
|
|
31
|
+
this.negate = false;
|
|
32
|
+
if (this.long) {
|
|
33
|
+
this.negate = this.long.startsWith('--no-');
|
|
34
|
+
}
|
|
30
35
|
this.description = description || '';
|
|
31
36
|
this.defaultValue = undefined;
|
|
32
37
|
}
|
|
@@ -39,7 +44,10 @@ class Option {
|
|
|
39
44
|
*/
|
|
40
45
|
|
|
41
46
|
name() {
|
|
42
|
-
|
|
47
|
+
if (this.long) {
|
|
48
|
+
return this.long.replace(/^--/, '');
|
|
49
|
+
}
|
|
50
|
+
return this.short.replace(/^-/, '');
|
|
43
51
|
};
|
|
44
52
|
|
|
45
53
|
/**
|
|
@@ -110,6 +118,7 @@ class Command extends EventEmitter {
|
|
|
110
118
|
this._name = name || '';
|
|
111
119
|
this._optionValues = {};
|
|
112
120
|
this._storeOptionsAsProperties = true; // backwards compatible by default
|
|
121
|
+
this._storeOptionsAsPropertiesCalled = false;
|
|
113
122
|
this._passCommandToAction = true; // backwards compatible by default
|
|
114
123
|
this._actionResults = [];
|
|
115
124
|
this._actionHandler = null;
|
|
@@ -118,8 +127,10 @@ class Command extends EventEmitter {
|
|
|
118
127
|
this._defaultCommandName = null;
|
|
119
128
|
this._exitCallback = null;
|
|
120
129
|
this._aliases = [];
|
|
130
|
+
this._combineFlagAndOptionalValue = true;
|
|
121
131
|
|
|
122
132
|
this._hidden = false;
|
|
133
|
+
this._hasHelpOption = true;
|
|
123
134
|
this._helpFlags = '-h, --help';
|
|
124
135
|
this._helpDescription = 'display help for command';
|
|
125
136
|
this._helpShortFlag = '-h';
|
|
@@ -175,6 +186,7 @@ class Command extends EventEmitter {
|
|
|
175
186
|
if (opts.isDefault) this._defaultCommandName = cmd._name;
|
|
176
187
|
|
|
177
188
|
cmd._hidden = !!(opts.noHelp || opts.hidden);
|
|
189
|
+
cmd._hasHelpOption = this._hasHelpOption;
|
|
178
190
|
cmd._helpFlags = this._helpFlags;
|
|
179
191
|
cmd._helpDescription = this._helpDescription;
|
|
180
192
|
cmd._helpShortFlag = this._helpShortFlag;
|
|
@@ -185,6 +197,7 @@ class Command extends EventEmitter {
|
|
|
185
197
|
cmd._exitCallback = this._exitCallback;
|
|
186
198
|
cmd._storeOptionsAsProperties = this._storeOptionsAsProperties;
|
|
187
199
|
cmd._passCommandToAction = this._passCommandToAction;
|
|
200
|
+
cmd._combineFlagAndOptionalValue = this._combineFlagAndOptionalValue;
|
|
188
201
|
|
|
189
202
|
cmd._executableFile = opts.executableFile || null; // Custom name for executable file, set missing to null to match constructor
|
|
190
203
|
this.commands.push(cmd);
|
|
@@ -260,7 +273,7 @@ class Command extends EventEmitter {
|
|
|
260
273
|
*
|
|
261
274
|
* addHelpCommand() // force on
|
|
262
275
|
* addHelpCommand(false); // force off
|
|
263
|
-
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom
|
|
276
|
+
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
|
|
264
277
|
*
|
|
265
278
|
* @return {Command} `this` command for chaining
|
|
266
279
|
* @api public
|
|
@@ -422,13 +435,56 @@ class Command extends EventEmitter {
|
|
|
422
435
|
return this;
|
|
423
436
|
};
|
|
424
437
|
|
|
438
|
+
/**
|
|
439
|
+
* Internal routine to check whether there is a clash storing option value with a Command property.
|
|
440
|
+
*
|
|
441
|
+
* @param {Option} option
|
|
442
|
+
* @api private
|
|
443
|
+
*/
|
|
444
|
+
|
|
445
|
+
_checkForOptionNameClash(option) {
|
|
446
|
+
if (!this._storeOptionsAsProperties || this._storeOptionsAsPropertiesCalled) {
|
|
447
|
+
// Storing options safely, or user has been explicit and up to them.
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
// User may override help, and hard to tell if worth warning.
|
|
451
|
+
if (option.name() === 'help') {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const commandProperty = this._getOptionValue(option.attributeName());
|
|
456
|
+
if (commandProperty === undefined) {
|
|
457
|
+
// no clash
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
let foundClash = true;
|
|
462
|
+
if (option.negate) {
|
|
463
|
+
// It is ok if define foo before --no-foo.
|
|
464
|
+
const positiveLongFlag = option.long.replace(/^--no-/, '--');
|
|
465
|
+
foundClash = !this._findOption(positiveLongFlag);
|
|
466
|
+
} else if (option.long) {
|
|
467
|
+
const negativeLongFlag = option.long.replace(/^--/, '--no-');
|
|
468
|
+
foundClash = !this._findOption(negativeLongFlag);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (foundClash) {
|
|
472
|
+
throw new Error(`option '${option.name()}' clashes with existing property '${option.attributeName()}' on Command
|
|
473
|
+
- call storeOptionsAsProperties(false) to store option values safely,
|
|
474
|
+
- or call storeOptionsAsProperties(true) to suppress this check,
|
|
475
|
+
- or change option name
|
|
476
|
+
|
|
477
|
+
Read more on https://git.io/JJc0W`);
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
|
|
425
481
|
/**
|
|
426
482
|
* Internal implementation shared by .option() and .requiredOption()
|
|
427
483
|
*
|
|
428
484
|
* @param {Object} config
|
|
429
485
|
* @param {string} flags
|
|
430
486
|
* @param {string} description
|
|
431
|
-
* @param {Function|*} [fn] - custom option processing function or default
|
|
487
|
+
* @param {Function|*} [fn] - custom option processing function or default value
|
|
432
488
|
* @param {*} [defaultValue]
|
|
433
489
|
* @return {Command} `this` command for chaining
|
|
434
490
|
* @api private
|
|
@@ -440,6 +496,8 @@ class Command extends EventEmitter {
|
|
|
440
496
|
const name = option.attributeName();
|
|
441
497
|
option.mandatory = !!config.mandatory;
|
|
442
498
|
|
|
499
|
+
this._checkForOptionNameClash(option);
|
|
500
|
+
|
|
443
501
|
// default as 3rd arg
|
|
444
502
|
if (typeof fn !== 'function') {
|
|
445
503
|
if (fn instanceof RegExp) {
|
|
@@ -476,13 +534,21 @@ class Command extends EventEmitter {
|
|
|
476
534
|
// when it's passed assign the value
|
|
477
535
|
// and conditionally invoke the callback
|
|
478
536
|
this.on('option:' + oname, (val) => {
|
|
479
|
-
|
|
537
|
+
const oldValue = this._getOptionValue(name);
|
|
538
|
+
|
|
539
|
+
// custom processing
|
|
480
540
|
if (val !== null && fn) {
|
|
481
|
-
val = fn(val,
|
|
541
|
+
val = fn(val, oldValue === undefined ? defaultValue : oldValue);
|
|
542
|
+
} else if (val !== null && option.variadic) {
|
|
543
|
+
if (oldValue === defaultValue || !Array.isArray(oldValue)) {
|
|
544
|
+
val = [val];
|
|
545
|
+
} else {
|
|
546
|
+
val = oldValue.concat(val);
|
|
547
|
+
}
|
|
482
548
|
}
|
|
483
549
|
|
|
484
550
|
// unassigned or boolean value
|
|
485
|
-
if (typeof
|
|
551
|
+
if (typeof oldValue === 'boolean' || typeof oldValue === 'undefined') {
|
|
486
552
|
// if no value, negate false, and we have a default, then use it!
|
|
487
553
|
if (val == null) {
|
|
488
554
|
this._setOptionValue(name, option.negate
|
|
@@ -546,7 +612,7 @@ class Command extends EventEmitter {
|
|
|
546
612
|
*
|
|
547
613
|
* @param {string} flags
|
|
548
614
|
* @param {string} description
|
|
549
|
-
* @param {Function|*} [fn] - custom option processing function or default
|
|
615
|
+
* @param {Function|*} [fn] - custom option processing function or default value
|
|
550
616
|
* @param {*} [defaultValue]
|
|
551
617
|
* @return {Command} `this` command for chaining
|
|
552
618
|
* @api public
|
|
@@ -556,7 +622,7 @@ class Command extends EventEmitter {
|
|
|
556
622
|
return this._optionEx({}, flags, description, fn, defaultValue);
|
|
557
623
|
};
|
|
558
624
|
|
|
559
|
-
|
|
625
|
+
/**
|
|
560
626
|
* Add a required option which must have a value after parsing. This usually means
|
|
561
627
|
* the option must be specified on the command line. (Otherwise the same as .option().)
|
|
562
628
|
*
|
|
@@ -564,7 +630,7 @@ class Command extends EventEmitter {
|
|
|
564
630
|
*
|
|
565
631
|
* @param {string} flags
|
|
566
632
|
* @param {string} description
|
|
567
|
-
* @param {Function|*} [fn] - custom option processing function or default
|
|
633
|
+
* @param {Function|*} [fn] - custom option processing function or default value
|
|
568
634
|
* @param {*} [defaultValue]
|
|
569
635
|
* @return {Command} `this` command for chaining
|
|
570
636
|
* @api public
|
|
@@ -574,6 +640,23 @@ class Command extends EventEmitter {
|
|
|
574
640
|
return this._optionEx({ mandatory: true }, flags, description, fn, defaultValue);
|
|
575
641
|
};
|
|
576
642
|
|
|
643
|
+
/**
|
|
644
|
+
* Alter parsing of short flags with optional values.
|
|
645
|
+
*
|
|
646
|
+
* Examples:
|
|
647
|
+
*
|
|
648
|
+
* // for `.option('-f,--flag [value]'):
|
|
649
|
+
* .combineFlagAndOptionalValue(true) // `-f80` is treated like `--flag=80`, this is the default behaviour
|
|
650
|
+
* .combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
|
|
651
|
+
*
|
|
652
|
+
* @param {Boolean} [arg] - if `true` or omitted, an optional value can be specified directly after the flag.
|
|
653
|
+
* @api public
|
|
654
|
+
*/
|
|
655
|
+
combineFlagAndOptionalValue(arg) {
|
|
656
|
+
this._combineFlagAndOptionalValue = (arg === undefined) || arg;
|
|
657
|
+
return this;
|
|
658
|
+
};
|
|
659
|
+
|
|
577
660
|
/**
|
|
578
661
|
* Allow unknown options on the command line.
|
|
579
662
|
*
|
|
@@ -596,6 +679,7 @@ class Command extends EventEmitter {
|
|
|
596
679
|
*/
|
|
597
680
|
|
|
598
681
|
storeOptionsAsProperties(value) {
|
|
682
|
+
this._storeOptionsAsPropertiesCalled = true;
|
|
599
683
|
this._storeOptionsAsProperties = (value === undefined) || value;
|
|
600
684
|
if (this.options.length) {
|
|
601
685
|
throw new Error('call .storeOptionsAsProperties() before adding options');
|
|
@@ -754,13 +838,17 @@ class Command extends EventEmitter {
|
|
|
754
838
|
_executeSubCommand(subcommand, args) {
|
|
755
839
|
args = args.slice();
|
|
756
840
|
let launchWithNode = false; // Use node for source targets so do not need to get permissions correct, and on Windows.
|
|
757
|
-
const sourceExt = ['.js', '.ts', '.mjs'];
|
|
841
|
+
const sourceExt = ['.js', '.ts', '.tsx', '.mjs'];
|
|
758
842
|
|
|
759
843
|
// Not checking for help first. Unlikely to have mandatory and executable, and can't robustly test for help flags in external command.
|
|
760
844
|
this._checkForMissingMandatoryOptions();
|
|
761
845
|
|
|
762
846
|
// Want the entry script as the reference for command name and directory for searching for other files.
|
|
763
|
-
|
|
847
|
+
let scriptPath = this._scriptPath;
|
|
848
|
+
// Fallback in case not set, due to how Command created or called.
|
|
849
|
+
if (!scriptPath && process.mainModule) {
|
|
850
|
+
scriptPath = process.mainModule.filename;
|
|
851
|
+
}
|
|
764
852
|
|
|
765
853
|
let baseDir;
|
|
766
854
|
try {
|
|
@@ -891,7 +979,7 @@ class Command extends EventEmitter {
|
|
|
891
979
|
this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
|
|
892
980
|
} else {
|
|
893
981
|
if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
|
|
894
|
-
//
|
|
982
|
+
// probably missing subcommand and no handler, user needs help
|
|
895
983
|
this._helpAndError();
|
|
896
984
|
}
|
|
897
985
|
|
|
@@ -998,6 +1086,7 @@ class Command extends EventEmitter {
|
|
|
998
1086
|
}
|
|
999
1087
|
|
|
1000
1088
|
// parse options
|
|
1089
|
+
let activeVariadicOption = null;
|
|
1001
1090
|
while (args.length) {
|
|
1002
1091
|
const arg = args.shift();
|
|
1003
1092
|
|
|
@@ -1008,6 +1097,12 @@ class Command extends EventEmitter {
|
|
|
1008
1097
|
break;
|
|
1009
1098
|
}
|
|
1010
1099
|
|
|
1100
|
+
if (activeVariadicOption && !maybeOption(arg)) {
|
|
1101
|
+
this.emit(`option:${activeVariadicOption.name()}`, arg);
|
|
1102
|
+
continue;
|
|
1103
|
+
}
|
|
1104
|
+
activeVariadicOption = null;
|
|
1105
|
+
|
|
1011
1106
|
if (maybeOption(arg)) {
|
|
1012
1107
|
const option = this._findOption(arg);
|
|
1013
1108
|
// recognised option, call listener to assign value with possible custom processing
|
|
@@ -1026,6 +1121,7 @@ class Command extends EventEmitter {
|
|
|
1026
1121
|
} else { // boolean flag
|
|
1027
1122
|
this.emit(`option:${option.name()}`);
|
|
1028
1123
|
}
|
|
1124
|
+
activeVariadicOption = option.variadic ? option : null;
|
|
1029
1125
|
continue;
|
|
1030
1126
|
}
|
|
1031
1127
|
}
|
|
@@ -1034,7 +1130,7 @@ class Command extends EventEmitter {
|
|
|
1034
1130
|
if (arg.length > 2 && arg[0] === '-' && arg[1] !== '-') {
|
|
1035
1131
|
const option = this._findOption(`-${arg[1]}`);
|
|
1036
1132
|
if (option) {
|
|
1037
|
-
if (option.required || option.optional) {
|
|
1133
|
+
if (option.required || (option.optional && this._combineFlagAndOptionalValue)) {
|
|
1038
1134
|
// option with value following in same argument
|
|
1039
1135
|
this.emit(`option:${option.name()}`, arg.slice(2));
|
|
1040
1136
|
} else {
|
|
@@ -1161,7 +1257,8 @@ class Command extends EventEmitter {
|
|
|
1161
1257
|
partCommands.unshift(parentCmd.name());
|
|
1162
1258
|
}
|
|
1163
1259
|
const fullCommand = partCommands.join(' ');
|
|
1164
|
-
const message = `error: unknown command '${this.args[0]}'
|
|
1260
|
+
const message = `error: unknown command '${this.args[0]}'.` +
|
|
1261
|
+
(this._hasHelpOption ? ` See '${fullCommand} ${this._helpLongFlag}'.` : '');
|
|
1165
1262
|
console.error(message);
|
|
1166
1263
|
this._exit(1, 'commander.unknownCommand', message);
|
|
1167
1264
|
};
|
|
@@ -1187,9 +1284,9 @@ class Command extends EventEmitter {
|
|
|
1187
1284
|
flags = flags || '-V, --version';
|
|
1188
1285
|
description = description || 'output the version number';
|
|
1189
1286
|
const versionOption = new Option(flags, description);
|
|
1190
|
-
this._versionOptionName = versionOption.
|
|
1287
|
+
this._versionOptionName = versionOption.attributeName();
|
|
1191
1288
|
this.options.push(versionOption);
|
|
1192
|
-
this.on('option:' +
|
|
1289
|
+
this.on('option:' + versionOption.name(), () => {
|
|
1193
1290
|
process.stdout.write(str + '\n');
|
|
1194
1291
|
this._exit(0, 'commander.version', str);
|
|
1195
1292
|
});
|
|
@@ -1270,9 +1367,11 @@ class Command extends EventEmitter {
|
|
|
1270
1367
|
const args = this._args.map((arg) => {
|
|
1271
1368
|
return humanReadableArgName(arg);
|
|
1272
1369
|
});
|
|
1273
|
-
return
|
|
1274
|
-
(this.
|
|
1275
|
-
(this.
|
|
1370
|
+
return [].concat(
|
|
1371
|
+
(this.options.length || this._hasHelpOption ? '[options]' : []),
|
|
1372
|
+
(this.commands.length ? '[command]' : []),
|
|
1373
|
+
(this._args.length ? args : [])
|
|
1374
|
+
).join(' ');
|
|
1276
1375
|
}
|
|
1277
1376
|
|
|
1278
1377
|
this._usage = str;
|
|
@@ -1415,8 +1514,8 @@ class Command extends EventEmitter {
|
|
|
1415
1514
|
});
|
|
1416
1515
|
|
|
1417
1516
|
// Implicit help
|
|
1418
|
-
const showShortHelpFlag = this._helpShortFlag && !this._findOption(this._helpShortFlag);
|
|
1419
|
-
const showLongHelpFlag = !this._findOption(this._helpLongFlag);
|
|
1517
|
+
const showShortHelpFlag = this._hasHelpOption && this._helpShortFlag && !this._findOption(this._helpShortFlag);
|
|
1518
|
+
const showLongHelpFlag = this._hasHelpOption && !this._findOption(this._helpLongFlag);
|
|
1420
1519
|
if (showShortHelpFlag || showLongHelpFlag) {
|
|
1421
1520
|
let helpFlags = this._helpFlags;
|
|
1422
1521
|
if (!showShortHelpFlag) {
|
|
@@ -1477,9 +1576,8 @@ class Command extends EventEmitter {
|
|
|
1477
1576
|
const columns = process.stdout.columns || 80;
|
|
1478
1577
|
const descriptionWidth = columns - width - 5;
|
|
1479
1578
|
desc.push('Arguments:');
|
|
1480
|
-
desc.push('');
|
|
1481
1579
|
this._args.forEach((arg) => {
|
|
1482
|
-
desc.push(' ' + pad(arg.name, width) + ' ' + wrap(argsDescription[arg.name], descriptionWidth, width + 4));
|
|
1580
|
+
desc.push(' ' + pad(arg.name, width) + ' ' + wrap(argsDescription[arg.name] || '', descriptionWidth, width + 4));
|
|
1483
1581
|
});
|
|
1484
1582
|
desc.push('');
|
|
1485
1583
|
}
|
|
@@ -1502,11 +1600,14 @@ class Command extends EventEmitter {
|
|
|
1502
1600
|
const commandHelp = this.commandHelp();
|
|
1503
1601
|
if (commandHelp) cmds = [commandHelp];
|
|
1504
1602
|
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1603
|
+
let options = [];
|
|
1604
|
+
if (this._hasHelpOption || this.options.length > 0) {
|
|
1605
|
+
options = [
|
|
1606
|
+
'Options:',
|
|
1607
|
+
'' + this.optionHelp().replace(/^/gm, ' '),
|
|
1608
|
+
''
|
|
1609
|
+
];
|
|
1610
|
+
}
|
|
1510
1611
|
|
|
1511
1612
|
return usage
|
|
1512
1613
|
.concat(desc)
|
|
@@ -1540,24 +1641,26 @@ class Command extends EventEmitter {
|
|
|
1540
1641
|
|
|
1541
1642
|
/**
|
|
1542
1643
|
* You can pass in flags and a description to override the help
|
|
1543
|
-
* flags and help description for your command.
|
|
1644
|
+
* flags and help description for your command. Pass in false to
|
|
1645
|
+
* disable the built-in help option.
|
|
1544
1646
|
*
|
|
1545
|
-
* @param {string} [flags]
|
|
1647
|
+
* @param {string | boolean} [flags]
|
|
1546
1648
|
* @param {string} [description]
|
|
1547
1649
|
* @return {Command} `this` command for chaining
|
|
1548
1650
|
* @api public
|
|
1549
1651
|
*/
|
|
1550
1652
|
|
|
1551
1653
|
helpOption(flags, description) {
|
|
1654
|
+
if (typeof flags === 'boolean') {
|
|
1655
|
+
this._hasHelpOption = flags;
|
|
1656
|
+
return this;
|
|
1657
|
+
}
|
|
1552
1658
|
this._helpFlags = flags || this._helpFlags;
|
|
1553
1659
|
this._helpDescription = description || this._helpDescription;
|
|
1554
1660
|
|
|
1555
|
-
const
|
|
1556
|
-
|
|
1557
|
-
this.
|
|
1558
|
-
if (splitFlags.length > 1) this._helpShortFlag = splitFlags.shift();
|
|
1559
|
-
|
|
1560
|
-
this._helpLongFlag = splitFlags.shift();
|
|
1661
|
+
const helpFlags = _parseOptionFlags(this._helpFlags);
|
|
1662
|
+
this._helpShortFlag = helpFlags.shortFlag;
|
|
1663
|
+
this._helpLongFlag = helpFlags.longFlag;
|
|
1561
1664
|
|
|
1562
1665
|
return this;
|
|
1563
1666
|
};
|
|
@@ -1684,7 +1787,7 @@ function optionalWrap(str, width, indent) {
|
|
|
1684
1787
|
*/
|
|
1685
1788
|
|
|
1686
1789
|
function outputHelpIfRequested(cmd, args) {
|
|
1687
|
-
const helpOption = args.find(arg => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
|
|
1790
|
+
const helpOption = cmd._hasHelpOption && args.find(arg => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
|
|
1688
1791
|
if (helpOption) {
|
|
1689
1792
|
cmd.outputHelp();
|
|
1690
1793
|
// (Do not have all displayed text available so only passing placeholder.)
|
|
@@ -1708,6 +1811,28 @@ function humanReadableArgName(arg) {
|
|
|
1708
1811
|
: '[' + nameOutput + ']';
|
|
1709
1812
|
}
|
|
1710
1813
|
|
|
1814
|
+
/**
|
|
1815
|
+
* Parse the short and long flag out of something like '-m,--mixed <value>'
|
|
1816
|
+
*
|
|
1817
|
+
* @api private
|
|
1818
|
+
*/
|
|
1819
|
+
|
|
1820
|
+
function _parseOptionFlags(flags) {
|
|
1821
|
+
let shortFlag;
|
|
1822
|
+
let longFlag;
|
|
1823
|
+
// Use original very loose parsing to maintain backwards compatibility for now,
|
|
1824
|
+
// which allowed for example unintended `-sw, --short-word` [sic].
|
|
1825
|
+
const flagParts = flags.split(/[ |,]+/);
|
|
1826
|
+
if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1])) shortFlag = flagParts.shift();
|
|
1827
|
+
longFlag = flagParts.shift();
|
|
1828
|
+
// Add support for lone short flag without significantly changing parsing!
|
|
1829
|
+
if (!shortFlag && /^-[^-]$/.test(longFlag)) {
|
|
1830
|
+
shortFlag = longFlag;
|
|
1831
|
+
longFlag = undefined;
|
|
1832
|
+
}
|
|
1833
|
+
return { shortFlag, longFlag };
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1711
1836
|
/**
|
|
1712
1837
|
* Scan arguments and increment port number for inspect calls (to avoid conflicts when spawning new command).
|
|
1713
1838
|
*
|
|
@@ -1722,35 +1847,35 @@ function incrementNodeInspectorPort(args) {
|
|
|
1722
1847
|
// --inspect-brk[=[host:]port]
|
|
1723
1848
|
// --inspect-port=[host:]port
|
|
1724
1849
|
return args.map((arg) => {
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
}
|
|
1743
|
-
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
|
1744
|
-
// e.g. --inspect=localhost:1234
|
|
1745
|
-
debugOption = match[1];
|
|
1850
|
+
if (!arg.startsWith('--inspect')) {
|
|
1851
|
+
return arg;
|
|
1852
|
+
}
|
|
1853
|
+
let debugOption;
|
|
1854
|
+
let debugHost = '127.0.0.1';
|
|
1855
|
+
let debugPort = '9229';
|
|
1856
|
+
let match;
|
|
1857
|
+
if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
|
|
1858
|
+
// e.g. --inspect
|
|
1859
|
+
debugOption = match[1];
|
|
1860
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
|
|
1861
|
+
debugOption = match[1];
|
|
1862
|
+
if (/^\d+$/.test(match[3])) {
|
|
1863
|
+
// e.g. --inspect=1234
|
|
1864
|
+
debugPort = match[3];
|
|
1865
|
+
} else {
|
|
1866
|
+
// e.g. --inspect=localhost
|
|
1746
1867
|
debugHost = match[3];
|
|
1747
|
-
debugPort = match[4];
|
|
1748
1868
|
}
|
|
1869
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
|
1870
|
+
// e.g. --inspect=localhost:1234
|
|
1871
|
+
debugOption = match[1];
|
|
1872
|
+
debugHost = match[3];
|
|
1873
|
+
debugPort = match[4];
|
|
1874
|
+
}
|
|
1749
1875
|
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
}
|
|
1876
|
+
if (debugOption && debugPort !== '0') {
|
|
1877
|
+
return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
|
|
1753
1878
|
}
|
|
1754
|
-
return
|
|
1879
|
+
return arg;
|
|
1755
1880
|
});
|
|
1756
1881
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.2.1",
|
|
4
4
|
"description": "the complete solution for node.js command-line programs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"commander",
|
|
@@ -31,17 +31,20 @@
|
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/jest": "^
|
|
35
|
-
"@types/node": "^
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
37
|
-
"eslint": "^
|
|
38
|
-
"eslint-config-standard-with-typescript": "^
|
|
39
|
-
"eslint-plugin-jest": "^
|
|
40
|
-
"jest": "^
|
|
41
|
-
"standard": "^
|
|
42
|
-
"typescript": "^
|
|
34
|
+
"@types/jest": "^26.0.15",
|
|
35
|
+
"@types/node": "^14.14.2",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^4.5.0",
|
|
37
|
+
"eslint": "^7.11.0",
|
|
38
|
+
"eslint-config-standard-with-typescript": "^19.0.1",
|
|
39
|
+
"eslint-plugin-jest": "^24.1.0",
|
|
40
|
+
"jest": "^26.6.0",
|
|
41
|
+
"standard": "^15.0.0",
|
|
42
|
+
"typescript": "^4.0.3"
|
|
43
43
|
},
|
|
44
44
|
"typings": "typings/index.d.ts",
|
|
45
|
+
"jest": {
|
|
46
|
+
"collectCoverage": true
|
|
47
|
+
},
|
|
45
48
|
"engines": {
|
|
46
49
|
"node": ">= 6"
|
|
47
50
|
}
|
package/typings/index.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ declare namespace commander {
|
|
|
75
75
|
* ```ts
|
|
76
76
|
* program
|
|
77
77
|
* .command('start <service>', 'start named service')
|
|
78
|
-
* .command('stop [service]', 'stop named
|
|
78
|
+
* .command('stop [service]', 'stop named service, or all if no name supplied');
|
|
79
79
|
* ```
|
|
80
80
|
*
|
|
81
81
|
* @param nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
|
|
@@ -109,6 +109,17 @@ declare namespace commander {
|
|
|
109
109
|
*/
|
|
110
110
|
arguments(desc: string): this;
|
|
111
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Override default decision whether to add implicit help command.
|
|
114
|
+
*
|
|
115
|
+
* addHelpCommand() // force on
|
|
116
|
+
* addHelpCommand(false); // force off
|
|
117
|
+
* addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
|
|
118
|
+
*
|
|
119
|
+
* @returns `this` command for chaining
|
|
120
|
+
*/
|
|
121
|
+
addHelpCommand(enableOrNameAndArgs?: string | boolean, description?: string): this;
|
|
122
|
+
|
|
112
123
|
/**
|
|
113
124
|
* Register callback to use as replacement for calling process.exit.
|
|
114
125
|
*/
|
|
@@ -201,6 +212,18 @@ declare namespace commander {
|
|
|
201
212
|
*/
|
|
202
213
|
passCommandToAction(value?: boolean): this;
|
|
203
214
|
|
|
215
|
+
/**
|
|
216
|
+
* Alter parsing of short flags with optional values.
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* // for `.option('-f,--flag [value]'):
|
|
220
|
+
* .combineFlagAndOptionalValue(true) // `-f80` is treated like `--flag=80`, this is the default behaviour
|
|
221
|
+
* .combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
|
|
222
|
+
*
|
|
223
|
+
* @returns `this` command for chaining
|
|
224
|
+
*/
|
|
225
|
+
combineFlagAndOptionalValue(arg?: boolean): this;
|
|
226
|
+
|
|
204
227
|
/**
|
|
205
228
|
* Allow unknown options on the command line.
|
|
206
229
|
*
|
|
@@ -335,9 +358,10 @@ declare namespace commander {
|
|
|
335
358
|
|
|
336
359
|
/**
|
|
337
360
|
* You can pass in flags and a description to override the help
|
|
338
|
-
* flags and help description for your command.
|
|
361
|
+
* flags and help description for your command. Pass in false
|
|
362
|
+
* to disable the built-in help option.
|
|
339
363
|
*/
|
|
340
|
-
helpOption(flags?: string, description?: string): this;
|
|
364
|
+
helpOption(flags?: string | boolean, description?: string): this;
|
|
341
365
|
|
|
342
366
|
/**
|
|
343
367
|
* Output help information and exit.
|
|
@@ -381,6 +405,6 @@ declare namespace commander {
|
|
|
381
405
|
}
|
|
382
406
|
|
|
383
407
|
// Declaring namespace AND global
|
|
384
|
-
// eslint-disable-next-line no-redeclare
|
|
408
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
385
409
|
declare const commander: commander.CommanderStatic;
|
|
386
410
|
export = commander;
|