commander 2.5.0 → 2.7.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/History.md +239 -0
- package/LICENSE +22 -0
- package/Readme.md +146 -74
- package/index.js +96 -26
- package/package.json +30 -12
package/History.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
|
|
2
|
+
2.7.1 / 2015-03-11
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
* Revert #347 (fix collisions when option and first arg have same name) which causes a bug in #367.
|
|
6
|
+
|
|
7
|
+
2.7.0 / 2015-03-09
|
|
8
|
+
==================
|
|
9
|
+
|
|
10
|
+
* Fix git-style bug when installed globally. Close #335 #349 @zhiyelee
|
|
11
|
+
* Fix collisions when option and first arg have same name. Close #346 #347 @tonylukasavage
|
|
12
|
+
* Add support for camelCase on `opts()`. Close #353 @nkzawa
|
|
13
|
+
* Add node.js 0.12 and io.js to travis.yml
|
|
14
|
+
* Allow RegEx options. #337 @palanik
|
|
15
|
+
* Fixes exit code when sub-command failing. Close #260 #332 @pirelenito
|
|
16
|
+
* git-style `bin` files in $PATH make sense. Close #196 #327 @zhiyelee
|
|
17
|
+
|
|
18
|
+
2.6.0 / 2014-12-30
|
|
19
|
+
==================
|
|
20
|
+
|
|
21
|
+
* added `Command#allowUnknownOption` method. Close #138 #318 @doozr @zhiyelee
|
|
22
|
+
* Add application description to the help msg. Close #112 @dalssoft
|
|
23
|
+
|
|
24
|
+
2.5.1 / 2014-12-15
|
|
25
|
+
==================
|
|
26
|
+
|
|
27
|
+
* fixed two bugs incurred by variadic arguments. Close #291 @Quentin01 #302 @zhiyelee
|
|
28
|
+
|
|
29
|
+
2.5.0 / 2014-10-24
|
|
30
|
+
==================
|
|
31
|
+
|
|
32
|
+
* add support for variadic arguments. Closes #277 @whitlockjc
|
|
33
|
+
|
|
34
|
+
2.4.0 / 2014-10-17
|
|
35
|
+
==================
|
|
36
|
+
|
|
37
|
+
* fixed a bug on executing the coercion function of subcommands option. Closes #270
|
|
38
|
+
* added `Command.prototype.name` to retrieve command name. Closes #264 #266 @tonylukasavage
|
|
39
|
+
* added `Command.prototype.opts` to retrieve all the options as a simple object of key-value pairs. Closes #262 @tonylukasavage
|
|
40
|
+
* fixed a bug on subcommand name. Closes #248 @jonathandelgado
|
|
41
|
+
* fixed function normalize doesn’t honor option terminator. Closes #216 @abbr
|
|
42
|
+
|
|
43
|
+
2.3.0 / 2014-07-16
|
|
44
|
+
==================
|
|
45
|
+
|
|
46
|
+
* add command alias'. Closes PR #210
|
|
47
|
+
* fix: Typos. Closes #99
|
|
48
|
+
* fix: Unused fs module. Closes #217
|
|
49
|
+
|
|
50
|
+
2.2.0 / 2014-03-29
|
|
51
|
+
==================
|
|
52
|
+
|
|
53
|
+
* add passing of previous option value
|
|
54
|
+
* fix: support subcommands on windows. Closes #142
|
|
55
|
+
* Now the defaultValue passed as the second argument of the coercion function.
|
|
56
|
+
|
|
57
|
+
2.1.0 / 2013-11-21
|
|
58
|
+
==================
|
|
59
|
+
|
|
60
|
+
* add: allow cflag style option params, unit test, fixes #174
|
|
61
|
+
|
|
62
|
+
2.0.0 / 2013-07-18
|
|
63
|
+
==================
|
|
64
|
+
|
|
65
|
+
* remove input methods (.prompt, .confirm, etc)
|
|
66
|
+
|
|
67
|
+
1.3.2 / 2013-07-18
|
|
68
|
+
==================
|
|
69
|
+
|
|
70
|
+
* add support for sub-commands to co-exist with the original command
|
|
71
|
+
|
|
72
|
+
1.3.1 / 2013-07-18
|
|
73
|
+
==================
|
|
74
|
+
|
|
75
|
+
* add quick .runningCommand hack so you can opt-out of other logic when running a sub command
|
|
76
|
+
|
|
77
|
+
1.3.0 / 2013-07-09
|
|
78
|
+
==================
|
|
79
|
+
|
|
80
|
+
* add EACCES error handling
|
|
81
|
+
* fix sub-command --help
|
|
82
|
+
|
|
83
|
+
1.2.0 / 2013-06-13
|
|
84
|
+
==================
|
|
85
|
+
|
|
86
|
+
* allow "-" hyphen as an option argument
|
|
87
|
+
* support for RegExp coercion
|
|
88
|
+
|
|
89
|
+
1.1.1 / 2012-11-20
|
|
90
|
+
==================
|
|
91
|
+
|
|
92
|
+
* add more sub-command padding
|
|
93
|
+
* fix .usage() when args are present. Closes #106
|
|
94
|
+
|
|
95
|
+
1.1.0 / 2012-11-16
|
|
96
|
+
==================
|
|
97
|
+
|
|
98
|
+
* add git-style executable subcommand support. Closes #94
|
|
99
|
+
|
|
100
|
+
1.0.5 / 2012-10-09
|
|
101
|
+
==================
|
|
102
|
+
|
|
103
|
+
* fix `--name` clobbering. Closes #92
|
|
104
|
+
* fix examples/help. Closes #89
|
|
105
|
+
|
|
106
|
+
1.0.4 / 2012-09-03
|
|
107
|
+
==================
|
|
108
|
+
|
|
109
|
+
* add `outputHelp()` method.
|
|
110
|
+
|
|
111
|
+
1.0.3 / 2012-08-30
|
|
112
|
+
==================
|
|
113
|
+
|
|
114
|
+
* remove invalid .version() defaulting
|
|
115
|
+
|
|
116
|
+
1.0.2 / 2012-08-24
|
|
117
|
+
==================
|
|
118
|
+
|
|
119
|
+
* add `--foo=bar` support [arv]
|
|
120
|
+
* fix password on node 0.8.8. Make backward compatible with 0.6 [focusaurus]
|
|
121
|
+
|
|
122
|
+
1.0.1 / 2012-08-03
|
|
123
|
+
==================
|
|
124
|
+
|
|
125
|
+
* fix issue #56
|
|
126
|
+
* fix tty.setRawMode(mode) was moved to tty.ReadStream#setRawMode() (i.e. process.stdin.setRawMode())
|
|
127
|
+
|
|
128
|
+
1.0.0 / 2012-07-05
|
|
129
|
+
==================
|
|
130
|
+
|
|
131
|
+
* add support for optional option descriptions
|
|
132
|
+
* add defaulting of `.version()` to package.json's version
|
|
133
|
+
|
|
134
|
+
0.6.1 / 2012-06-01
|
|
135
|
+
==================
|
|
136
|
+
|
|
137
|
+
* Added: append (yes or no) on confirmation
|
|
138
|
+
* Added: allow node.js v0.7.x
|
|
139
|
+
|
|
140
|
+
0.6.0 / 2012-04-10
|
|
141
|
+
==================
|
|
142
|
+
|
|
143
|
+
* Added `.prompt(obj, callback)` support. Closes #49
|
|
144
|
+
* Added default support to .choose(). Closes #41
|
|
145
|
+
* Fixed the choice example
|
|
146
|
+
|
|
147
|
+
0.5.1 / 2011-12-20
|
|
148
|
+
==================
|
|
149
|
+
|
|
150
|
+
* Fixed `password()` for recent nodes. Closes #36
|
|
151
|
+
|
|
152
|
+
0.5.0 / 2011-12-04
|
|
153
|
+
==================
|
|
154
|
+
|
|
155
|
+
* Added sub-command option support [itay]
|
|
156
|
+
|
|
157
|
+
0.4.3 / 2011-12-04
|
|
158
|
+
==================
|
|
159
|
+
|
|
160
|
+
* Fixed custom help ordering. Closes #32
|
|
161
|
+
|
|
162
|
+
0.4.2 / 2011-11-24
|
|
163
|
+
==================
|
|
164
|
+
|
|
165
|
+
* Added travis support
|
|
166
|
+
* Fixed: line-buffered input automatically trimmed. Closes #31
|
|
167
|
+
|
|
168
|
+
0.4.1 / 2011-11-18
|
|
169
|
+
==================
|
|
170
|
+
|
|
171
|
+
* Removed listening for "close" on --help
|
|
172
|
+
|
|
173
|
+
0.4.0 / 2011-11-15
|
|
174
|
+
==================
|
|
175
|
+
|
|
176
|
+
* Added support for `--`. Closes #24
|
|
177
|
+
|
|
178
|
+
0.3.3 / 2011-11-14
|
|
179
|
+
==================
|
|
180
|
+
|
|
181
|
+
* Fixed: wait for close event when writing help info [Jerry Hamlet]
|
|
182
|
+
|
|
183
|
+
0.3.2 / 2011-11-01
|
|
184
|
+
==================
|
|
185
|
+
|
|
186
|
+
* Fixed long flag definitions with values [felixge]
|
|
187
|
+
|
|
188
|
+
0.3.1 / 2011-10-31
|
|
189
|
+
==================
|
|
190
|
+
|
|
191
|
+
* Changed `--version` short flag to `-V` from `-v`
|
|
192
|
+
* Changed `.version()` so it's configurable [felixge]
|
|
193
|
+
|
|
194
|
+
0.3.0 / 2011-10-31
|
|
195
|
+
==================
|
|
196
|
+
|
|
197
|
+
* Added support for long flags only. Closes #18
|
|
198
|
+
|
|
199
|
+
0.2.1 / 2011-10-24
|
|
200
|
+
==================
|
|
201
|
+
|
|
202
|
+
* "node": ">= 0.4.x < 0.7.0". Closes #20
|
|
203
|
+
|
|
204
|
+
0.2.0 / 2011-09-26
|
|
205
|
+
==================
|
|
206
|
+
|
|
207
|
+
* Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs]
|
|
208
|
+
|
|
209
|
+
0.1.0 / 2011-08-24
|
|
210
|
+
==================
|
|
211
|
+
|
|
212
|
+
* Added support for custom `--help` output
|
|
213
|
+
|
|
214
|
+
0.0.5 / 2011-08-18
|
|
215
|
+
==================
|
|
216
|
+
|
|
217
|
+
* Changed: when the user enters nothing prompt for password again
|
|
218
|
+
* Fixed issue with passwords beginning with numbers [NuckChorris]
|
|
219
|
+
|
|
220
|
+
0.0.4 / 2011-08-15
|
|
221
|
+
==================
|
|
222
|
+
|
|
223
|
+
* Fixed `Commander#args`
|
|
224
|
+
|
|
225
|
+
0.0.3 / 2011-08-15
|
|
226
|
+
==================
|
|
227
|
+
|
|
228
|
+
* Added default option value support
|
|
229
|
+
|
|
230
|
+
0.0.2 / 2011-08-15
|
|
231
|
+
==================
|
|
232
|
+
|
|
233
|
+
* Added mask support to `Command#password(str[, mask], fn)`
|
|
234
|
+
* Added `Command#password(str, fn)`
|
|
235
|
+
|
|
236
|
+
0.0.1 / 2010-01-03
|
|
237
|
+
==================
|
|
238
|
+
|
|
239
|
+
* Initial release
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(The MIT License)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/Readme.md
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# Commander.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
[](http://travis-ci.org/tj/commander.js)
|
|
4
5
|
[](https://www.npmjs.org/package/commander)
|
|
5
6
|
[](https://www.npmjs.org/package/commander)
|
|
7
|
+
[](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
6
8
|
|
|
7
|
-
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/tj/commander).
|
|
9
|
+
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/tj/commander).
|
|
10
|
+
[API documentation](http://tj.github.com/commander.js/)
|
|
8
11
|
|
|
9
12
|
|
|
10
13
|
## Installation
|
|
@@ -41,6 +44,62 @@ console.log(' - %s cheese', program.cheese);
|
|
|
41
44
|
|
|
42
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.
|
|
43
46
|
|
|
47
|
+
|
|
48
|
+
## Coercion
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
function range(val) {
|
|
52
|
+
return val.split('..').map(Number);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function list(val) {
|
|
56
|
+
return val.split(',');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function collect(val, memo) {
|
|
60
|
+
memo.push(val);
|
|
61
|
+
return memo;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function increaseVerbosity(v, total) {
|
|
65
|
+
return total + 1;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
program
|
|
69
|
+
.version('0.0.1')
|
|
70
|
+
.usage('[options] <file ...>')
|
|
71
|
+
.option('-i, --integer <n>', 'An integer argument', parseInt)
|
|
72
|
+
.option('-f, --float <n>', 'A float argument', parseFloat)
|
|
73
|
+
.option('-r, --range <a>..<b>', 'A range', range)
|
|
74
|
+
.option('-l, --list <items>', 'A list', list)
|
|
75
|
+
.option('-o, --optional [value]', 'An optional value')
|
|
76
|
+
.option('-c, --collect [value]', 'A repeatable value', collect, [])
|
|
77
|
+
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
|
|
78
|
+
.parse(process.argv);
|
|
79
|
+
|
|
80
|
+
console.log(' int: %j', program.integer);
|
|
81
|
+
console.log(' float: %j', program.float);
|
|
82
|
+
console.log(' optional: %j', program.optional);
|
|
83
|
+
program.range = program.range || [];
|
|
84
|
+
console.log(' range: %j..%j', program.range[0], program.range[1]);
|
|
85
|
+
console.log(' list: %j', program.list);
|
|
86
|
+
console.log(' collect: %j', program.collect);
|
|
87
|
+
console.log(' verbosity: %j', program.verbose);
|
|
88
|
+
console.log(' args: %j', program.args);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Regular Expression
|
|
92
|
+
```js
|
|
93
|
+
program
|
|
94
|
+
.version('0.0.1')
|
|
95
|
+
.option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
|
|
96
|
+
.option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
|
|
97
|
+
.parse(process.argv);
|
|
98
|
+
|
|
99
|
+
console.log(' size: %j', program.size);
|
|
100
|
+
console.log(' drink: %j', program.drink);
|
|
101
|
+
```
|
|
102
|
+
|
|
44
103
|
## Variadic arguments
|
|
45
104
|
|
|
46
105
|
The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to
|
|
@@ -73,6 +132,25 @@ program.parse(process.argv);
|
|
|
73
132
|
An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed
|
|
74
133
|
to your action as demonstrated above.
|
|
75
134
|
|
|
135
|
+
## Git-style sub-commands
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
// file: ./examples/pm
|
|
139
|
+
var program = require('..');
|
|
140
|
+
|
|
141
|
+
program
|
|
142
|
+
.version('0.0.1')
|
|
143
|
+
.command('install [name]', 'install one or more packages')
|
|
144
|
+
.command('search [query]', 'search with optional query')
|
|
145
|
+
.command('list', 'list packages installed')
|
|
146
|
+
.parse(process.argv);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
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.
|
|
150
|
+
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`.
|
|
151
|
+
|
|
152
|
+
If the program is designed to installed globally, make sure the executables have proper modes, like `755`.
|
|
153
|
+
|
|
76
154
|
## Automated --help
|
|
77
155
|
|
|
78
156
|
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
|
|
@@ -82,60 +160,20 @@ program.parse(process.argv);
|
|
|
82
160
|
|
|
83
161
|
Usage: pizza [options]
|
|
84
162
|
|
|
163
|
+
An application for pizzas ordering
|
|
164
|
+
|
|
85
165
|
Options:
|
|
86
166
|
|
|
167
|
+
-h, --help output usage information
|
|
87
168
|
-V, --version output the version number
|
|
88
169
|
-p, --peppers Add peppers
|
|
89
170
|
-P, --pineapple Add pineapple
|
|
90
171
|
-b, --bbq Add bbq sauce
|
|
91
172
|
-c, --cheese <type> Add the specified type of cheese [marble]
|
|
92
|
-
-
|
|
173
|
+
-C, --no-cheese You do not want any cheese
|
|
93
174
|
|
|
94
175
|
```
|
|
95
176
|
|
|
96
|
-
## Coercion
|
|
97
|
-
|
|
98
|
-
```js
|
|
99
|
-
function range(val) {
|
|
100
|
-
return val.split('..').map(Number);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function list(val) {
|
|
104
|
-
return val.split(',');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function collect(val, memo) {
|
|
108
|
-
memo.push(val);
|
|
109
|
-
return memo;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function increaseVerbosity(v, total) {
|
|
113
|
-
return total + 1;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
program
|
|
117
|
-
.version('0.0.1')
|
|
118
|
-
.usage('[options] <file ...>')
|
|
119
|
-
.option('-i, --integer <n>', 'An integer argument', parseInt)
|
|
120
|
-
.option('-f, --float <n>', 'A float argument', parseFloat)
|
|
121
|
-
.option('-r, --range <a>..<b>', 'A range', range)
|
|
122
|
-
.option('-l, --list <items>', 'A list', list)
|
|
123
|
-
.option('-o, --optional [value]', 'An optional value')
|
|
124
|
-
.option('-c, --collect [value]', 'A repeatable value', collect, [])
|
|
125
|
-
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
|
|
126
|
-
.parse(process.argv);
|
|
127
|
-
|
|
128
|
-
console.log(' int: %j', program.integer);
|
|
129
|
-
console.log(' float: %j', program.float);
|
|
130
|
-
console.log(' optional: %j', program.optional);
|
|
131
|
-
program.range = program.range || [];
|
|
132
|
-
console.log(' range: %j..%j', program.range[0], program.range[1]);
|
|
133
|
-
console.log(' list: %j', program.list);
|
|
134
|
-
console.log(' collect: %j', program.collect);
|
|
135
|
-
console.log(' verbosity: %j', program.verbose);
|
|
136
|
-
console.log(' args: %j', program.args);
|
|
137
|
-
```
|
|
138
|
-
|
|
139
177
|
## Custom help
|
|
140
178
|
|
|
141
179
|
You can display arbitrary `-h, --help` information
|
|
@@ -152,7 +190,7 @@ console.log(' args: %j', program.args);
|
|
|
152
190
|
* Module dependencies.
|
|
153
191
|
*/
|
|
154
192
|
|
|
155
|
-
var program = require('
|
|
193
|
+
var program = require('commander');
|
|
156
194
|
|
|
157
195
|
program
|
|
158
196
|
.version('0.0.1')
|
|
@@ -176,7 +214,7 @@ program.parse(process.argv);
|
|
|
176
214
|
console.log('stuff');
|
|
177
215
|
```
|
|
178
216
|
|
|
179
|
-
|
|
217
|
+
Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
|
|
180
218
|
|
|
181
219
|
```
|
|
182
220
|
|
|
@@ -199,41 +237,75 @@ Examples:
|
|
|
199
237
|
|
|
200
238
|
## .outputHelp()
|
|
201
239
|
|
|
202
|
-
|
|
240
|
+
Output help information without exiting.
|
|
241
|
+
|
|
242
|
+
If you want to display help by default (e.g. if no command was provided), you can use something like:
|
|
243
|
+
|
|
244
|
+
```js
|
|
245
|
+
var program = require('commander');
|
|
246
|
+
|
|
247
|
+
program
|
|
248
|
+
.version('0.0.1')
|
|
249
|
+
.command('getstream [url]', 'get stream URL')
|
|
250
|
+
.parse(process.argv);
|
|
251
|
+
|
|
252
|
+
if (!process.argv.slice(2).length) {
|
|
253
|
+
program.outputHelp();
|
|
254
|
+
}
|
|
255
|
+
```
|
|
203
256
|
|
|
204
257
|
## .help()
|
|
205
258
|
|
|
206
259
|
Output help information and exit immediately.
|
|
207
260
|
|
|
208
|
-
##
|
|
261
|
+
## Examples
|
|
209
262
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
- [progress bars](https://github.com/tj/node-progress)
|
|
213
|
-
- [more progress bars](https://github.com/substack/node-multimeter)
|
|
214
|
-
- [examples](https://github.com/tj/commander.js/tree/master/examples)
|
|
263
|
+
```js
|
|
264
|
+
var program = require('commander');
|
|
215
265
|
|
|
216
|
-
|
|
266
|
+
program
|
|
267
|
+
.version('0.0.1')
|
|
268
|
+
.option('-C, --chdir <path>', 'change the working directory')
|
|
269
|
+
.option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
|
|
270
|
+
.option('-T, --no-tests', 'ignore test hook')
|
|
271
|
+
|
|
272
|
+
program
|
|
273
|
+
.command('setup [env]')
|
|
274
|
+
.description('run setup commands for all envs')
|
|
275
|
+
.option("-s, --setup_mode [mode]", "Which setup mode to use")
|
|
276
|
+
.action(function(env, options){
|
|
277
|
+
var mode = options.setup_mode || "normal";
|
|
278
|
+
env = env || 'all';
|
|
279
|
+
console.log('setup for %s env(s) with %s mode', env, mode);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
program
|
|
283
|
+
.command('exec <cmd>')
|
|
284
|
+
.alias('ex')
|
|
285
|
+
.description('execute the given remote cmd')
|
|
286
|
+
.option("-e, --exec_mode <mode>", "Which exec mode to use")
|
|
287
|
+
.action(function(cmd, options){
|
|
288
|
+
console.log('exec "%s" using %s mode', cmd, options.exec_mode);
|
|
289
|
+
}).on('--help', function() {
|
|
290
|
+
console.log(' Examples:');
|
|
291
|
+
console.log();
|
|
292
|
+
console.log(' $ deploy exec sequential');
|
|
293
|
+
console.log(' $ deploy exec async');
|
|
294
|
+
console.log();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
program
|
|
298
|
+
.command('*')
|
|
299
|
+
.action(function(env){
|
|
300
|
+
console.log('deploying "%s"', env);
|
|
301
|
+
});
|
|
217
302
|
|
|
218
|
-
(
|
|
303
|
+
program.parse(process.argv);
|
|
304
|
+
```
|
|
219
305
|
|
|
220
|
-
|
|
306
|
+
More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
|
|
221
307
|
|
|
222
|
-
|
|
223
|
-
a copy of this software and associated documentation files (the
|
|
224
|
-
'Software'), to deal in the Software without restriction, including
|
|
225
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
|
226
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
|
227
|
-
permit persons to whom the Software is furnished to do so, subject to
|
|
228
|
-
the following conditions:
|
|
308
|
+
## License
|
|
229
309
|
|
|
230
|
-
|
|
231
|
-
included in all copies or substantial portions of the Software.
|
|
310
|
+
MIT
|
|
232
311
|
|
|
233
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
234
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
235
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
236
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
237
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
238
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
239
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/index.js
CHANGED
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
var EventEmitter = require('events').EventEmitter;
|
|
7
7
|
var spawn = require('child_process').spawn;
|
|
8
|
+
var readlink = require('graceful-readlink').readlinkSync;
|
|
8
9
|
var path = require('path');
|
|
9
10
|
var dirname = path.dirname;
|
|
10
11
|
var basename = path.basename;
|
|
12
|
+
var fs = require('fs');
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Expose the root command.
|
|
@@ -82,6 +84,7 @@ function Command(name) {
|
|
|
82
84
|
this.commands = [];
|
|
83
85
|
this.options = [];
|
|
84
86
|
this._execs = [];
|
|
87
|
+
this._allowUnknownOption = false;
|
|
85
88
|
this._args = [];
|
|
86
89
|
this._name = name;
|
|
87
90
|
}
|
|
@@ -148,7 +151,7 @@ Command.prototype.__proto__ = EventEmitter.prototype;
|
|
|
148
151
|
* program.parse(process.argv);
|
|
149
152
|
*
|
|
150
153
|
* @param {String} name
|
|
151
|
-
* @param {String} [desc]
|
|
154
|
+
* @param {String} [desc] for git-style sub-commands
|
|
152
155
|
* @return {Command} the new command
|
|
153
156
|
* @api public
|
|
154
157
|
*/
|
|
@@ -156,12 +159,17 @@ Command.prototype.__proto__ = EventEmitter.prototype;
|
|
|
156
159
|
Command.prototype.command = function(name, desc) {
|
|
157
160
|
var args = name.split(/ +/);
|
|
158
161
|
var cmd = new Command(args.shift());
|
|
159
|
-
|
|
160
|
-
if (desc)
|
|
161
|
-
|
|
162
|
+
|
|
163
|
+
if (desc) {
|
|
164
|
+
cmd.description(desc);
|
|
165
|
+
this.executables = true;
|
|
166
|
+
this._execs[cmd._name] = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
162
169
|
this.commands.push(cmd);
|
|
163
170
|
cmd.parseExpectedArgs(args);
|
|
164
171
|
cmd.parent = this;
|
|
172
|
+
|
|
165
173
|
if (desc) return this;
|
|
166
174
|
return cmd;
|
|
167
175
|
};
|
|
@@ -207,11 +215,10 @@ Command.prototype.parseExpectedArgs = function(args) {
|
|
|
207
215
|
break;
|
|
208
216
|
}
|
|
209
217
|
|
|
210
|
-
if (argDetails.name.
|
|
218
|
+
if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
|
|
211
219
|
argDetails.variadic = true;
|
|
212
220
|
argDetails.name = argDetails.name.slice(0, -3);
|
|
213
221
|
}
|
|
214
|
-
|
|
215
222
|
if (argDetails.name) {
|
|
216
223
|
self._args.push(argDetails);
|
|
217
224
|
}
|
|
@@ -266,7 +273,7 @@ Command.prototype.action = function(fn) {
|
|
|
266
273
|
self.variadicArgNotLast(arg.name);
|
|
267
274
|
}
|
|
268
275
|
|
|
269
|
-
args[i] = args.
|
|
276
|
+
args[i] = args.splice(i);
|
|
270
277
|
}
|
|
271
278
|
});
|
|
272
279
|
|
|
@@ -343,8 +350,17 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
|
343
350
|
|
|
344
351
|
// default as 3rd arg
|
|
345
352
|
if (typeof fn != 'function') {
|
|
346
|
-
|
|
347
|
-
|
|
353
|
+
if (fn instanceof RegExp) {
|
|
354
|
+
var regex = fn;
|
|
355
|
+
fn = function(val, def) {
|
|
356
|
+
var m = regex.exec(val);
|
|
357
|
+
return m ? m[0] : def;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
defaultValue = fn;
|
|
362
|
+
fn = null;
|
|
363
|
+
}
|
|
348
364
|
}
|
|
349
365
|
|
|
350
366
|
// preassign default value only for --no-*, [optional], or <required>
|
|
@@ -385,6 +401,18 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
|
385
401
|
return this;
|
|
386
402
|
};
|
|
387
403
|
|
|
404
|
+
/**
|
|
405
|
+
* Allow unknown options on the command line.
|
|
406
|
+
*
|
|
407
|
+
* @param {Boolean} arg if `true` or omitted, no error will be thrown
|
|
408
|
+
* for unknown options.
|
|
409
|
+
* @api public
|
|
410
|
+
*/
|
|
411
|
+
Command.prototype.allowUnknownOption = function(arg) {
|
|
412
|
+
this._allowUnknownOption = arguments.length === 0 || arg;
|
|
413
|
+
return this;
|
|
414
|
+
};
|
|
415
|
+
|
|
388
416
|
/**
|
|
389
417
|
* Parse `argv`, settings options and invoking commands when defined.
|
|
390
418
|
*
|
|
@@ -440,22 +468,42 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
440
468
|
}
|
|
441
469
|
|
|
442
470
|
// executable
|
|
443
|
-
var
|
|
444
|
-
var
|
|
471
|
+
var f = argv[1];
|
|
472
|
+
var link = readlink(f);
|
|
473
|
+
if (link !== f && link.charAt(0) !== '/') {
|
|
474
|
+
link = path.join(dirname(f), link)
|
|
475
|
+
}
|
|
476
|
+
var dir = dirname(link);
|
|
477
|
+
var bin = basename(f, '.js') + '-' + args[0];
|
|
445
478
|
|
|
446
|
-
//
|
|
479
|
+
// prefer local `./<bin>` to bin in the $PATH
|
|
447
480
|
var local = path.join(dir, bin);
|
|
481
|
+
try {
|
|
482
|
+
// for versions before node v0.8 when there weren't `fs.existsSync`
|
|
483
|
+
if (fs.statSync(local).isFile()) {
|
|
484
|
+
bin = local;
|
|
485
|
+
}
|
|
486
|
+
} catch (e) {}
|
|
448
487
|
|
|
449
488
|
// run it
|
|
450
489
|
args = args.slice(1);
|
|
451
|
-
|
|
452
|
-
var proc
|
|
490
|
+
|
|
491
|
+
var proc;
|
|
492
|
+
if (process.platform !== 'win32') {
|
|
493
|
+
proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });
|
|
494
|
+
} else {
|
|
495
|
+
args.unshift(local);
|
|
496
|
+
proc = spawn(process.execPath, args, { stdio: 'inherit'});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
proc.on('close', process.exit.bind(process));
|
|
453
500
|
proc.on('error', function(err) {
|
|
454
501
|
if (err.code == "ENOENT") {
|
|
455
502
|
console.error('\n %s(1) does not exist, try --help\n', bin);
|
|
456
503
|
} else if (err.code == "EACCES") {
|
|
457
504
|
console.error('\n %s(1) not executable. try chmod or run with root\n', bin);
|
|
458
505
|
}
|
|
506
|
+
process.exit(1);
|
|
459
507
|
});
|
|
460
508
|
|
|
461
509
|
this.runningCommand = proc;
|
|
@@ -644,7 +692,7 @@ Command.prototype.opts = function() {
|
|
|
644
692
|
, len = this.options.length;
|
|
645
693
|
|
|
646
694
|
for (var i = 0 ; i < len; i++) {
|
|
647
|
-
var key = this.options[i].name();
|
|
695
|
+
var key = camelcase(this.options[i].name());
|
|
648
696
|
result[key] = key === 'version' ? this._version : this[key];
|
|
649
697
|
}
|
|
650
698
|
return result;
|
|
@@ -691,6 +739,7 @@ Command.prototype.optionMissingArgument = function(option, flag) {
|
|
|
691
739
|
*/
|
|
692
740
|
|
|
693
741
|
Command.prototype.unknownOption = function(flag) {
|
|
742
|
+
if (this._allowUnknownOption) return;
|
|
694
743
|
console.error();
|
|
695
744
|
console.error(" error: unknown option `%s'", flag);
|
|
696
745
|
console.error();
|
|
@@ -794,7 +843,7 @@ Command.prototype.usage = function(str) {
|
|
|
794
843
|
* @api public
|
|
795
844
|
*/
|
|
796
845
|
|
|
797
|
-
Command.prototype.name = function(
|
|
846
|
+
Command.prototype.name = function() {
|
|
798
847
|
return this._name;
|
|
799
848
|
};
|
|
800
849
|
|
|
@@ -880,20 +929,41 @@ Command.prototype.commandHelp = function() {
|
|
|
880
929
|
*/
|
|
881
930
|
|
|
882
931
|
Command.prototype.helpInformation = function() {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
932
|
+
var desc = [];
|
|
933
|
+
if (this._description) {
|
|
934
|
+
desc = [
|
|
935
|
+
' ' + this._description
|
|
936
|
+
, ''
|
|
937
|
+
];
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
var cmdName = this._name;
|
|
941
|
+
if (this._alias) {
|
|
942
|
+
cmdName = cmdName + '|' + this._alias;
|
|
943
|
+
}
|
|
944
|
+
var usage = [
|
|
945
|
+
''
|
|
946
|
+
,' Usage: ' + cmdName + ' ' + this.usage()
|
|
947
|
+
, ''
|
|
948
|
+
];
|
|
949
|
+
|
|
950
|
+
var cmds = [];
|
|
951
|
+
var commandHelp = this.commandHelp();
|
|
952
|
+
if (commandHelp) cmds = [commandHelp];
|
|
953
|
+
|
|
954
|
+
var options = [
|
|
955
|
+
' Options:'
|
|
892
956
|
, ''
|
|
893
957
|
, '' + this.optionHelp().replace(/^/gm, ' ')
|
|
894
958
|
, ''
|
|
895
959
|
, ''
|
|
896
|
-
]
|
|
960
|
+
];
|
|
961
|
+
|
|
962
|
+
return usage
|
|
963
|
+
.concat(cmds)
|
|
964
|
+
.concat(desc)
|
|
965
|
+
.concat(options)
|
|
966
|
+
.join('\n');
|
|
897
967
|
};
|
|
898
968
|
|
|
899
969
|
/**
|
package/package.json
CHANGED
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
"name": "commander",
|
|
3
|
+
"version": "2.7.1",
|
|
4
|
+
"description": "the complete solution for node.js command-line programs",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"command",
|
|
7
|
+
"option",
|
|
8
|
+
"parser"
|
|
9
|
+
],
|
|
10
|
+
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/tj/commander.js.git"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"should": ">= 0.0.1"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "make test"
|
|
21
|
+
},
|
|
22
|
+
"main": "index",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">= 0.6.x"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"index.js"
|
|
28
|
+
],
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"graceful-readlink": ">= 1.0.0"
|
|
31
|
+
}
|
|
14
32
|
}
|