commander 2.2.0 → 2.5.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/Readme.md +61 -13
- package/index.js +221 -88
- package/package.json +4 -3
package/Readme.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# Commander.js
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](http://travis-ci.org/tj/commander.js)
|
|
4
|
+
[](https://www.npmjs.org/package/commander)
|
|
5
|
+
[](https://www.npmjs.org/package/commander)
|
|
6
|
+
|
|
7
|
+
The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/tj/commander).
|
|
8
|
+
API documentation: [http://tj.github.com/commander.js/](http://tj.github.com/commander.js/)
|
|
4
9
|
|
|
5
|
-
[](http://travis-ci.org/visionmedia/commander.js)
|
|
6
10
|
|
|
7
11
|
## Installation
|
|
8
12
|
|
|
@@ -38,6 +42,55 @@ console.log(' - %s cheese', program.cheese);
|
|
|
38
42
|
|
|
39
43
|
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.
|
|
40
44
|
|
|
45
|
+
## Variadic arguments
|
|
46
|
+
|
|
47
|
+
The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to
|
|
48
|
+
append `...` to the argument name. Here is an example:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
#!/usr/bin/env node
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Module dependencies.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
var program = require('commander');
|
|
58
|
+
|
|
59
|
+
program
|
|
60
|
+
.version('0.0.1')
|
|
61
|
+
.command('rmdir <dir> [otherDirs...]')
|
|
62
|
+
.action(function (dir, otherDirs) {
|
|
63
|
+
console.log('rmdir %s', dir);
|
|
64
|
+
if (otherDirs) {
|
|
65
|
+
otherDirs.forEach(function (oDir) {
|
|
66
|
+
console.log('rmdir %s', oDir);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
program.parse(process.argv);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed
|
|
75
|
+
to your action as demonstrated above.
|
|
76
|
+
|
|
77
|
+
## Git-style sub-commands
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
// file: ./examples/pm
|
|
81
|
+
var program = require('..');
|
|
82
|
+
|
|
83
|
+
program
|
|
84
|
+
.version('0.0.1')
|
|
85
|
+
.command('install [name]', 'install one or more packages')
|
|
86
|
+
.command('search [query]', 'search with optional query')
|
|
87
|
+
.command('list', 'list packages installed')
|
|
88
|
+
.parse(process.argv);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
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.
|
|
92
|
+
The commander will try to find the executable script in __current directory__ with the name `scriptBasename-subcommand`, like `pm-install`, `pm-search`.
|
|
93
|
+
|
|
41
94
|
## Automated --help
|
|
42
95
|
|
|
43
96
|
The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
|
|
@@ -86,7 +139,7 @@ program
|
|
|
86
139
|
.option('-r, --range <a>..<b>', 'A range', range)
|
|
87
140
|
.option('-l, --list <items>', 'A list', list)
|
|
88
141
|
.option('-o, --optional [value]', 'An optional value')
|
|
89
|
-
.option('-c, --collect [value]', 'A repeatable value', [])
|
|
142
|
+
.option('-c, --collect [value]', 'A repeatable value', collect, [])
|
|
90
143
|
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
|
|
91
144
|
.parse(process.argv);
|
|
92
145
|
|
|
@@ -117,11 +170,7 @@ console.log(' args: %j', program.args);
|
|
|
117
170
|
* Module dependencies.
|
|
118
171
|
*/
|
|
119
172
|
|
|
120
|
-
var program = require('
|
|
121
|
-
|
|
122
|
-
function list(val) {
|
|
123
|
-
return val.split(',').map(Number);
|
|
124
|
-
}
|
|
173
|
+
var program = require('commander');
|
|
125
174
|
|
|
126
175
|
program
|
|
127
176
|
.version('0.0.1')
|
|
@@ -145,7 +194,7 @@ program.parse(process.argv);
|
|
|
145
194
|
console.log('stuff');
|
|
146
195
|
```
|
|
147
196
|
|
|
148
|
-
|
|
197
|
+
Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
|
|
149
198
|
|
|
150
199
|
```
|
|
151
200
|
|
|
@@ -176,13 +225,12 @@ Examples:
|
|
|
176
225
|
|
|
177
226
|
## Links
|
|
178
227
|
|
|
179
|
-
- [API documentation](http://visionmedia.github.com/commander.js/)
|
|
180
228
|
- [ascii tables](https://github.com/LearnBoost/cli-table)
|
|
181
|
-
- [progress bars](https://github.com/
|
|
229
|
+
- [progress bars](https://github.com/tj/node-progress)
|
|
182
230
|
- [more progress bars](https://github.com/substack/node-multimeter)
|
|
183
|
-
- [examples](https://github.com/
|
|
231
|
+
- [examples](https://github.com/tj/commander.js/tree/master/examples)
|
|
184
232
|
|
|
185
|
-
## License
|
|
233
|
+
## License
|
|
186
234
|
|
|
187
235
|
(The MIT License)
|
|
188
236
|
|
package/index.js
CHANGED
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
|
|
6
6
|
var EventEmitter = require('events').EventEmitter;
|
|
7
7
|
var spawn = require('child_process').spawn;
|
|
8
|
-
var fs = require('fs');
|
|
9
|
-
var exists = fs.existsSync;
|
|
10
8
|
var path = require('path');
|
|
11
9
|
var dirname = path.dirname;
|
|
12
10
|
var basename = path.basename;
|
|
@@ -15,7 +13,7 @@ var basename = path.basename;
|
|
|
15
13
|
* Expose the root command.
|
|
16
14
|
*/
|
|
17
15
|
|
|
18
|
-
exports = module.exports = new Command;
|
|
16
|
+
exports = module.exports = new Command();
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
19
|
* Expose `Command`.
|
|
@@ -55,7 +53,7 @@ function Option(flags, description) {
|
|
|
55
53
|
* @api private
|
|
56
54
|
*/
|
|
57
55
|
|
|
58
|
-
Option.prototype.name = function(){
|
|
56
|
+
Option.prototype.name = function() {
|
|
59
57
|
return this.long
|
|
60
58
|
.replace('--', '')
|
|
61
59
|
.replace('no-', '');
|
|
@@ -69,9 +67,8 @@ Option.prototype.name = function(){
|
|
|
69
67
|
* @api private
|
|
70
68
|
*/
|
|
71
69
|
|
|
72
|
-
Option.prototype.is = function(arg){
|
|
73
|
-
return arg == this.short
|
|
74
|
-
|| arg == this.long;
|
|
70
|
+
Option.prototype.is = function(arg) {
|
|
71
|
+
return arg == this.short || arg == this.long;
|
|
75
72
|
};
|
|
76
73
|
|
|
77
74
|
/**
|
|
@@ -118,41 +115,58 @@ Command.prototype.__proto__ = EventEmitter.prototype;
|
|
|
118
115
|
* program
|
|
119
116
|
* .command('setup')
|
|
120
117
|
* .description('run remote setup commands')
|
|
121
|
-
* .action(function(){
|
|
118
|
+
* .action(function() {
|
|
122
119
|
* console.log('setup');
|
|
123
120
|
* });
|
|
124
121
|
*
|
|
125
122
|
* program
|
|
126
123
|
* .command('exec <cmd>')
|
|
127
124
|
* .description('run the given remote command')
|
|
128
|
-
* .action(function(cmd){
|
|
125
|
+
* .action(function(cmd) {
|
|
129
126
|
* console.log('exec "%s"', cmd);
|
|
130
127
|
* });
|
|
131
128
|
*
|
|
132
129
|
* program
|
|
130
|
+
* .command('teardown <dir> [otherDirs...]')
|
|
131
|
+
* .description('run teardown commands')
|
|
132
|
+
* .action(function(dir, otherDirs) {
|
|
133
|
+
* console.log('dir "%s"', dir);
|
|
134
|
+
* if (otherDirs) {
|
|
135
|
+
* otherDirs.forEach(function (oDir) {
|
|
136
|
+
* console.log('dir "%s"', oDir);
|
|
137
|
+
* });
|
|
138
|
+
* }
|
|
139
|
+
* });
|
|
140
|
+
*
|
|
141
|
+
* program
|
|
133
142
|
* .command('*')
|
|
134
143
|
* .description('deploy the given env')
|
|
135
|
-
* .action(function(env){
|
|
144
|
+
* .action(function(env) {
|
|
136
145
|
* console.log('deploying "%s"', env);
|
|
137
146
|
* });
|
|
138
147
|
*
|
|
139
148
|
* program.parse(process.argv);
|
|
140
149
|
*
|
|
141
150
|
* @param {String} name
|
|
142
|
-
* @param {String} [desc]
|
|
151
|
+
* @param {String} [desc] for git-style sub-commands
|
|
143
152
|
* @return {Command} the new command
|
|
144
153
|
* @api public
|
|
145
154
|
*/
|
|
146
155
|
|
|
147
|
-
Command.prototype.command = function(name, desc){
|
|
156
|
+
Command.prototype.command = function(name, desc) {
|
|
148
157
|
var args = name.split(/ +/);
|
|
149
158
|
var cmd = new Command(args.shift());
|
|
150
|
-
|
|
151
|
-
if (desc)
|
|
152
|
-
|
|
159
|
+
|
|
160
|
+
if (desc) {
|
|
161
|
+
cmd.description(desc);
|
|
162
|
+
this.executables = true;
|
|
163
|
+
this._execs[cmd._name] = true;
|
|
164
|
+
}
|
|
165
|
+
|
|
153
166
|
this.commands.push(cmd);
|
|
154
167
|
cmd.parseExpectedArgs(args);
|
|
155
168
|
cmd.parent = this;
|
|
169
|
+
|
|
156
170
|
if (desc) return this;
|
|
157
171
|
return cmd;
|
|
158
172
|
};
|
|
@@ -178,18 +192,33 @@ Command.prototype.addImplicitHelpCommand = function() {
|
|
|
178
192
|
* @api public
|
|
179
193
|
*/
|
|
180
194
|
|
|
181
|
-
Command.prototype.parseExpectedArgs = function(args){
|
|
195
|
+
Command.prototype.parseExpectedArgs = function(args) {
|
|
182
196
|
if (!args.length) return;
|
|
183
197
|
var self = this;
|
|
184
|
-
args.forEach(function(arg){
|
|
198
|
+
args.forEach(function(arg) {
|
|
199
|
+
var argDetails = {
|
|
200
|
+
required: false,
|
|
201
|
+
name: '',
|
|
202
|
+
variadic: false
|
|
203
|
+
};
|
|
204
|
+
|
|
185
205
|
switch (arg[0]) {
|
|
186
206
|
case '<':
|
|
187
|
-
|
|
207
|
+
argDetails.required = true;
|
|
208
|
+
argDetails.name = arg.slice(1, -1);
|
|
188
209
|
break;
|
|
189
210
|
case '[':
|
|
190
|
-
|
|
211
|
+
argDetails.name = arg.slice(1, -1);
|
|
191
212
|
break;
|
|
192
213
|
}
|
|
214
|
+
|
|
215
|
+
if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
|
|
216
|
+
argDetails.variadic = true;
|
|
217
|
+
argDetails.name = argDetails.name.slice(0, -3);
|
|
218
|
+
}
|
|
219
|
+
if (argDetails.name) {
|
|
220
|
+
self._args.push(argDetails);
|
|
221
|
+
}
|
|
193
222
|
});
|
|
194
223
|
return this;
|
|
195
224
|
};
|
|
@@ -202,7 +231,7 @@ Command.prototype.parseExpectedArgs = function(args){
|
|
|
202
231
|
* program
|
|
203
232
|
* .command('help')
|
|
204
233
|
* .description('display verbose help')
|
|
205
|
-
* .action(function(){
|
|
234
|
+
* .action(function() {
|
|
206
235
|
* // output help here
|
|
207
236
|
* });
|
|
208
237
|
*
|
|
@@ -211,11 +240,13 @@ Command.prototype.parseExpectedArgs = function(args){
|
|
|
211
240
|
* @api public
|
|
212
241
|
*/
|
|
213
242
|
|
|
214
|
-
Command.prototype.action = function(fn){
|
|
243
|
+
Command.prototype.action = function(fn) {
|
|
215
244
|
var self = this;
|
|
216
|
-
|
|
245
|
+
var listener = function(args, unknown) {
|
|
217
246
|
// Parse any so-far unknown options
|
|
247
|
+
args = args || [];
|
|
218
248
|
unknown = unknown || [];
|
|
249
|
+
|
|
219
250
|
var parsed = self.parseOptions(unknown);
|
|
220
251
|
|
|
221
252
|
// Output help if necessary
|
|
@@ -231,9 +262,15 @@ Command.prototype.action = function(fn){
|
|
|
231
262
|
// Leftover arguments need to be pushed back. Fixes issue #56
|
|
232
263
|
if (parsed.args.length) args = parsed.args.concat(args);
|
|
233
264
|
|
|
234
|
-
self._args.forEach(function(arg, i){
|
|
265
|
+
self._args.forEach(function(arg, i) {
|
|
235
266
|
if (arg.required && null == args[i]) {
|
|
236
267
|
self.missingArgument(arg.name);
|
|
268
|
+
} else if (arg.variadic) {
|
|
269
|
+
if (i !== self._args.length - 1) {
|
|
270
|
+
self.variadicArgNotLast(arg.name);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
args[i] = args.splice(i);
|
|
237
274
|
}
|
|
238
275
|
});
|
|
239
276
|
|
|
@@ -246,8 +283,10 @@ Command.prototype.action = function(fn){
|
|
|
246
283
|
args.push(self);
|
|
247
284
|
}
|
|
248
285
|
|
|
249
|
-
fn.apply(
|
|
250
|
-
}
|
|
286
|
+
fn.apply(self, args);
|
|
287
|
+
};
|
|
288
|
+
this.parent.on(this._name, listener);
|
|
289
|
+
if (this._alias) this.parent.on(this._alias, listener);
|
|
251
290
|
return this;
|
|
252
291
|
};
|
|
253
292
|
|
|
@@ -272,7 +311,7 @@ Command.prototype.action = function(fn){
|
|
|
272
311
|
* program.pepper
|
|
273
312
|
* // => Boolean
|
|
274
313
|
*
|
|
275
|
-
* // simple boolean defaulting to
|
|
314
|
+
* // simple boolean defaulting to true
|
|
276
315
|
* program.option('-C, --no-cheese', 'remove cheese');
|
|
277
316
|
*
|
|
278
317
|
* program.cheese
|
|
@@ -280,7 +319,7 @@ Command.prototype.action = function(fn){
|
|
|
280
319
|
*
|
|
281
320
|
* --no-cheese
|
|
282
321
|
* program.cheese
|
|
283
|
-
* // =>
|
|
322
|
+
* // => false
|
|
284
323
|
*
|
|
285
324
|
* // required argument
|
|
286
325
|
* program.option('-C, --chdir <path>', 'change the working directory');
|
|
@@ -300,14 +339,17 @@ Command.prototype.action = function(fn){
|
|
|
300
339
|
* @api public
|
|
301
340
|
*/
|
|
302
341
|
|
|
303
|
-
Command.prototype.option = function(flags, description, fn, defaultValue){
|
|
342
|
+
Command.prototype.option = function(flags, description, fn, defaultValue) {
|
|
304
343
|
var self = this
|
|
305
344
|
, option = new Option(flags, description)
|
|
306
345
|
, oname = option.name()
|
|
307
346
|
, name = camelcase(oname);
|
|
308
347
|
|
|
309
348
|
// default as 3rd arg
|
|
310
|
-
if (
|
|
349
|
+
if (typeof fn != 'function') {
|
|
350
|
+
defaultValue = fn;
|
|
351
|
+
fn = null;
|
|
352
|
+
}
|
|
311
353
|
|
|
312
354
|
// preassign default value only for --no-*, [optional], or <required>
|
|
313
355
|
if (false == option.bool || option.optional || option.required) {
|
|
@@ -322,9 +364,11 @@ Command.prototype.option = function(flags, description, fn, defaultValue){
|
|
|
322
364
|
|
|
323
365
|
// when it's passed assign the value
|
|
324
366
|
// and conditionally invoke the callback
|
|
325
|
-
this.on(oname, function(val){
|
|
367
|
+
this.on(oname, function(val) {
|
|
326
368
|
// coercion
|
|
327
|
-
if (null !== val && fn) val = fn(val, undefined === self[name]
|
|
369
|
+
if (null !== val && fn) val = fn(val, undefined === self[name]
|
|
370
|
+
? defaultValue
|
|
371
|
+
: self[name]);
|
|
328
372
|
|
|
329
373
|
// unassigned or bool
|
|
330
374
|
if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) {
|
|
@@ -353,7 +397,7 @@ Command.prototype.option = function(flags, description, fn, defaultValue){
|
|
|
353
397
|
* @api public
|
|
354
398
|
*/
|
|
355
399
|
|
|
356
|
-
Command.prototype.parse = function(argv){
|
|
400
|
+
Command.prototype.parse = function(argv) {
|
|
357
401
|
// implicit help
|
|
358
402
|
if (this.executables) this.addImplicitHelpCommand();
|
|
359
403
|
|
|
@@ -371,7 +415,9 @@ Command.prototype.parse = function(argv){
|
|
|
371
415
|
|
|
372
416
|
// executable sub-commands
|
|
373
417
|
var name = result.args[0];
|
|
374
|
-
if (this._execs[name]
|
|
418
|
+
if (this._execs[name] && typeof this._execs[name] != "function") {
|
|
419
|
+
return this.executeSubCommand(argv, args, parsed.unknown);
|
|
420
|
+
}
|
|
375
421
|
|
|
376
422
|
return result;
|
|
377
423
|
};
|
|
@@ -408,7 +454,7 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
408
454
|
args = args.slice(1);
|
|
409
455
|
args.unshift(local);
|
|
410
456
|
var proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] });
|
|
411
|
-
proc.on('error', function(err){
|
|
457
|
+
proc.on('error', function(err) {
|
|
412
458
|
if (err.code == "ENOENT") {
|
|
413
459
|
console.error('\n %s(1) does not exist, try --help\n', bin);
|
|
414
460
|
} else if (err.code == "EACCES") {
|
|
@@ -429,7 +475,7 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
|
|
|
429
475
|
* @api private
|
|
430
476
|
*/
|
|
431
477
|
|
|
432
|
-
Command.prototype.normalize = function(args){
|
|
478
|
+
Command.prototype.normalize = function(args) {
|
|
433
479
|
var ret = []
|
|
434
480
|
, arg
|
|
435
481
|
, lastOpt
|
|
@@ -437,12 +483,18 @@ Command.prototype.normalize = function(args){
|
|
|
437
483
|
|
|
438
484
|
for (var i = 0, len = args.length; i < len; ++i) {
|
|
439
485
|
arg = args[i];
|
|
440
|
-
i > 0
|
|
486
|
+
if (i > 0) {
|
|
487
|
+
lastOpt = this.optionFor(args[i-1]);
|
|
488
|
+
}
|
|
441
489
|
|
|
442
|
-
if (
|
|
443
|
-
|
|
490
|
+
if (arg === '--') {
|
|
491
|
+
// Honor option terminator
|
|
492
|
+
ret = ret.concat(args.slice(i));
|
|
493
|
+
break;
|
|
494
|
+
} else if (lastOpt && lastOpt.required) {
|
|
495
|
+
ret.push(arg);
|
|
444
496
|
} else if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) {
|
|
445
|
-
arg.slice(1).split('').forEach(function(c){
|
|
497
|
+
arg.slice(1).split('').forEach(function(c) {
|
|
446
498
|
ret.push('-' + c);
|
|
447
499
|
});
|
|
448
500
|
} else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) {
|
|
@@ -467,10 +519,8 @@ Command.prototype.normalize = function(args){
|
|
|
467
519
|
* @api private
|
|
468
520
|
*/
|
|
469
521
|
|
|
470
|
-
Command.prototype.parseArgs = function(args, unknown){
|
|
471
|
-
var
|
|
472
|
-
, len = cmds.length
|
|
473
|
-
, name;
|
|
522
|
+
Command.prototype.parseArgs = function(args, unknown) {
|
|
523
|
+
var name;
|
|
474
524
|
|
|
475
525
|
if (args.length) {
|
|
476
526
|
name = args[0];
|
|
@@ -500,7 +550,7 @@ Command.prototype.parseArgs = function(args, unknown){
|
|
|
500
550
|
* @api private
|
|
501
551
|
*/
|
|
502
552
|
|
|
503
|
-
Command.prototype.optionFor = function(arg){
|
|
553
|
+
Command.prototype.optionFor = function(arg) {
|
|
504
554
|
for (var i = 0, len = this.options.length; i < len; ++i) {
|
|
505
555
|
if (this.options[i].is(arg)) {
|
|
506
556
|
return this.options[i];
|
|
@@ -517,7 +567,7 @@ Command.prototype.optionFor = function(arg){
|
|
|
517
567
|
* @api public
|
|
518
568
|
*/
|
|
519
569
|
|
|
520
|
-
Command.prototype.parseOptions = function(argv){
|
|
570
|
+
Command.prototype.parseOptions = function(argv) {
|
|
521
571
|
var args = []
|
|
522
572
|
, len = argv.length
|
|
523
573
|
, literal
|
|
@@ -587,6 +637,23 @@ Command.prototype.parseOptions = function(argv){
|
|
|
587
637
|
return { args: args, unknown: unknownOptions };
|
|
588
638
|
};
|
|
589
639
|
|
|
640
|
+
/**
|
|
641
|
+
* Return an object containing options as key-value pairs
|
|
642
|
+
*
|
|
643
|
+
* @return {Object}
|
|
644
|
+
* @api public
|
|
645
|
+
*/
|
|
646
|
+
Command.prototype.opts = function() {
|
|
647
|
+
var result = {}
|
|
648
|
+
, len = this.options.length;
|
|
649
|
+
|
|
650
|
+
for (var i = 0 ; i < len; i++) {
|
|
651
|
+
var key = this.options[i].name();
|
|
652
|
+
result[key] = key === 'version' ? this._version : this[key];
|
|
653
|
+
}
|
|
654
|
+
return result;
|
|
655
|
+
};
|
|
656
|
+
|
|
590
657
|
/**
|
|
591
658
|
* Argument `name` is missing.
|
|
592
659
|
*
|
|
@@ -594,7 +661,7 @@ Command.prototype.parseOptions = function(argv){
|
|
|
594
661
|
* @api private
|
|
595
662
|
*/
|
|
596
663
|
|
|
597
|
-
Command.prototype.missingArgument = function(name){
|
|
664
|
+
Command.prototype.missingArgument = function(name) {
|
|
598
665
|
console.error();
|
|
599
666
|
console.error(" error: missing required argument `%s'", name);
|
|
600
667
|
console.error();
|
|
@@ -609,7 +676,7 @@ Command.prototype.missingArgument = function(name){
|
|
|
609
676
|
* @api private
|
|
610
677
|
*/
|
|
611
678
|
|
|
612
|
-
Command.prototype.optionMissingArgument = function(option, flag){
|
|
679
|
+
Command.prototype.optionMissingArgument = function(option, flag) {
|
|
613
680
|
console.error();
|
|
614
681
|
if (flag) {
|
|
615
682
|
console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag);
|
|
@@ -627,13 +694,26 @@ Command.prototype.optionMissingArgument = function(option, flag){
|
|
|
627
694
|
* @api private
|
|
628
695
|
*/
|
|
629
696
|
|
|
630
|
-
Command.prototype.unknownOption = function(flag){
|
|
697
|
+
Command.prototype.unknownOption = function(flag) {
|
|
631
698
|
console.error();
|
|
632
699
|
console.error(" error: unknown option `%s'", flag);
|
|
633
700
|
console.error();
|
|
634
701
|
process.exit(1);
|
|
635
702
|
};
|
|
636
703
|
|
|
704
|
+
/**
|
|
705
|
+
* Variadic argument with `name` is not the last argument as required.
|
|
706
|
+
*
|
|
707
|
+
* @param {String} name
|
|
708
|
+
* @api private
|
|
709
|
+
*/
|
|
710
|
+
|
|
711
|
+
Command.prototype.variadicArgNotLast = function(name) {
|
|
712
|
+
console.error();
|
|
713
|
+
console.error(" error: variadic arguments must be last `%s'", name);
|
|
714
|
+
console.error();
|
|
715
|
+
process.exit(1);
|
|
716
|
+
};
|
|
637
717
|
|
|
638
718
|
/**
|
|
639
719
|
* Set the program version to `str`.
|
|
@@ -647,32 +727,46 @@ Command.prototype.unknownOption = function(flag){
|
|
|
647
727
|
* @api public
|
|
648
728
|
*/
|
|
649
729
|
|
|
650
|
-
Command.prototype.version = function(str, flags){
|
|
730
|
+
Command.prototype.version = function(str, flags) {
|
|
651
731
|
if (0 == arguments.length) return this._version;
|
|
652
732
|
this._version = str;
|
|
653
733
|
flags = flags || '-V, --version';
|
|
654
734
|
this.option(flags, 'output the version number');
|
|
655
|
-
this.on('version', function(){
|
|
656
|
-
|
|
735
|
+
this.on('version', function() {
|
|
736
|
+
process.stdout.write(str + '\n');
|
|
657
737
|
process.exit(0);
|
|
658
738
|
});
|
|
659
739
|
return this;
|
|
660
740
|
};
|
|
661
741
|
|
|
662
742
|
/**
|
|
663
|
-
* Set the description `str`.
|
|
743
|
+
* Set the description to `str`.
|
|
664
744
|
*
|
|
665
745
|
* @param {String} str
|
|
666
746
|
* @return {String|Command}
|
|
667
747
|
* @api public
|
|
668
748
|
*/
|
|
669
749
|
|
|
670
|
-
Command.prototype.description = function(str){
|
|
750
|
+
Command.prototype.description = function(str) {
|
|
671
751
|
if (0 == arguments.length) return this._description;
|
|
672
752
|
this._description = str;
|
|
673
753
|
return this;
|
|
674
754
|
};
|
|
675
755
|
|
|
756
|
+
/**
|
|
757
|
+
* Set an alias for the command
|
|
758
|
+
*
|
|
759
|
+
* @param {String} alias
|
|
760
|
+
* @return {String|Command}
|
|
761
|
+
* @api public
|
|
762
|
+
*/
|
|
763
|
+
|
|
764
|
+
Command.prototype.alias = function(alias) {
|
|
765
|
+
if (0 == arguments.length) return this._alias;
|
|
766
|
+
this._alias = alias;
|
|
767
|
+
return this;
|
|
768
|
+
};
|
|
769
|
+
|
|
676
770
|
/**
|
|
677
771
|
* Set / get the command usage `str`.
|
|
678
772
|
*
|
|
@@ -681,17 +775,14 @@ Command.prototype.description = function(str){
|
|
|
681
775
|
* @api public
|
|
682
776
|
*/
|
|
683
777
|
|
|
684
|
-
Command.prototype.usage = function(str){
|
|
685
|
-
var args = this._args.map(function(arg){
|
|
686
|
-
return arg
|
|
687
|
-
? '<' + arg.name + '>'
|
|
688
|
-
: '[' + arg.name + ']';
|
|
778
|
+
Command.prototype.usage = function(str) {
|
|
779
|
+
var args = this._args.map(function(arg) {
|
|
780
|
+
return humanReadableArgName(arg);
|
|
689
781
|
});
|
|
690
782
|
|
|
691
|
-
var usage = '[options'
|
|
692
|
-
+ (this.commands.length ? '
|
|
693
|
-
+ '
|
|
694
|
-
+ (this._args.length ? ' ' + args : '');
|
|
783
|
+
var usage = '[options]'
|
|
784
|
+
+ (this.commands.length ? ' [command]' : '')
|
|
785
|
+
+ (this._args.length ? ' ' + args.join(' ') : '');
|
|
695
786
|
|
|
696
787
|
if (0 == arguments.length) return this._usage || usage;
|
|
697
788
|
this._usage = str;
|
|
@@ -699,6 +790,18 @@ Command.prototype.usage = function(str){
|
|
|
699
790
|
return this;
|
|
700
791
|
};
|
|
701
792
|
|
|
793
|
+
/**
|
|
794
|
+
* Get the name of the command
|
|
795
|
+
*
|
|
796
|
+
* @param {String} name
|
|
797
|
+
* @return {String|Command}
|
|
798
|
+
* @api public
|
|
799
|
+
*/
|
|
800
|
+
|
|
801
|
+
Command.prototype.name = function(name) {
|
|
802
|
+
return this._name;
|
|
803
|
+
};
|
|
804
|
+
|
|
702
805
|
/**
|
|
703
806
|
* Return the largest option length.
|
|
704
807
|
*
|
|
@@ -706,8 +809,8 @@ Command.prototype.usage = function(str){
|
|
|
706
809
|
* @api private
|
|
707
810
|
*/
|
|
708
811
|
|
|
709
|
-
Command.prototype.largestOptionLength = function(){
|
|
710
|
-
return this.options.reduce(function(max, option){
|
|
812
|
+
Command.prototype.largestOptionLength = function() {
|
|
813
|
+
return this.options.reduce(function(max, option) {
|
|
711
814
|
return Math.max(max, option.flags.length);
|
|
712
815
|
}, 0);
|
|
713
816
|
};
|
|
@@ -719,14 +822,13 @@ Command.prototype.largestOptionLength = function(){
|
|
|
719
822
|
* @api private
|
|
720
823
|
*/
|
|
721
824
|
|
|
722
|
-
Command.prototype.optionHelp = function(){
|
|
825
|
+
Command.prototype.optionHelp = function() {
|
|
723
826
|
var width = this.largestOptionLength();
|
|
724
827
|
|
|
725
828
|
// Prepend the help information
|
|
726
829
|
return [pad('-h, --help', width) + ' ' + 'output usage information']
|
|
727
|
-
.concat(this.options.map(function(option){
|
|
728
|
-
return pad(option.flags, width)
|
|
729
|
-
+ ' ' + option.description;
|
|
830
|
+
.concat(this.options.map(function(option) {
|
|
831
|
+
return pad(option.flags, width) + ' ' + option.description;
|
|
730
832
|
}))
|
|
731
833
|
.join('\n');
|
|
732
834
|
};
|
|
@@ -738,26 +840,37 @@ Command.prototype.optionHelp = function(){
|
|
|
738
840
|
* @api private
|
|
739
841
|
*/
|
|
740
842
|
|
|
741
|
-
Command.prototype.commandHelp = function(){
|
|
843
|
+
Command.prototype.commandHelp = function() {
|
|
742
844
|
if (!this.commands.length) return '';
|
|
845
|
+
|
|
846
|
+
var commands = this.commands.map(function(cmd) {
|
|
847
|
+
var args = cmd._args.map(function(arg) {
|
|
848
|
+
return humanReadableArgName(arg);
|
|
849
|
+
}).join(' ');
|
|
850
|
+
|
|
851
|
+
return [
|
|
852
|
+
cmd._name
|
|
853
|
+
+ (cmd._alias
|
|
854
|
+
? '|' + cmd._alias
|
|
855
|
+
: '')
|
|
856
|
+
+ (cmd.options.length
|
|
857
|
+
? ' [options]'
|
|
858
|
+
: '')
|
|
859
|
+
+ ' ' + args
|
|
860
|
+
, cmd.description()
|
|
861
|
+
];
|
|
862
|
+
});
|
|
863
|
+
|
|
864
|
+
var width = commands.reduce(function(max, command) {
|
|
865
|
+
return Math.max(max, command[0].length);
|
|
866
|
+
}, 0);
|
|
867
|
+
|
|
743
868
|
return [
|
|
744
869
|
''
|
|
745
870
|
, ' Commands:'
|
|
746
871
|
, ''
|
|
747
|
-
,
|
|
748
|
-
|
|
749
|
-
return arg.required
|
|
750
|
-
? '<' + arg.name + '>'
|
|
751
|
-
: '[' + arg.name + ']';
|
|
752
|
-
}).join(' ');
|
|
753
|
-
|
|
754
|
-
return pad(cmd._name
|
|
755
|
-
+ (cmd.options.length
|
|
756
|
-
? ' [options]'
|
|
757
|
-
: '') + ' ' + args, 22)
|
|
758
|
-
+ (cmd.description()
|
|
759
|
-
? ' ' + cmd.description()
|
|
760
|
-
: '');
|
|
872
|
+
, commands.map(function(cmd) {
|
|
873
|
+
return pad(cmd[0], width) + ' ' + cmd[1];
|
|
761
874
|
}).join('\n').replace(/^/gm, ' ')
|
|
762
875
|
, ''
|
|
763
876
|
].join('\n');
|
|
@@ -770,10 +883,14 @@ Command.prototype.commandHelp = function(){
|
|
|
770
883
|
* @api private
|
|
771
884
|
*/
|
|
772
885
|
|
|
773
|
-
Command.prototype.helpInformation = function(){
|
|
886
|
+
Command.prototype.helpInformation = function() {
|
|
774
887
|
return [
|
|
775
888
|
''
|
|
776
|
-
, ' Usage: ' + this._name
|
|
889
|
+
, ' Usage: ' + this._name
|
|
890
|
+
+ (this._alias
|
|
891
|
+
? '|' + this._alias
|
|
892
|
+
: '')
|
|
893
|
+
+ ' ' + this.usage()
|
|
777
894
|
, '' + this.commandHelp()
|
|
778
895
|
, ' Options:'
|
|
779
896
|
, ''
|
|
@@ -789,7 +906,7 @@ Command.prototype.helpInformation = function(){
|
|
|
789
906
|
* @api public
|
|
790
907
|
*/
|
|
791
908
|
|
|
792
|
-
Command.prototype.outputHelp = function(){
|
|
909
|
+
Command.prototype.outputHelp = function() {
|
|
793
910
|
process.stdout.write(this.helpInformation());
|
|
794
911
|
this.emit('--help');
|
|
795
912
|
};
|
|
@@ -800,7 +917,7 @@ Command.prototype.outputHelp = function(){
|
|
|
800
917
|
* @api public
|
|
801
918
|
*/
|
|
802
919
|
|
|
803
|
-
Command.prototype.help = function(){
|
|
920
|
+
Command.prototype.help = function() {
|
|
804
921
|
this.outputHelp();
|
|
805
922
|
process.exit();
|
|
806
923
|
};
|
|
@@ -814,7 +931,7 @@ Command.prototype.help = function(){
|
|
|
814
931
|
*/
|
|
815
932
|
|
|
816
933
|
function camelcase(flag) {
|
|
817
|
-
return flag.split('-').reduce(function(str, word){
|
|
934
|
+
return flag.split('-').reduce(function(str, word) {
|
|
818
935
|
return str + word[0].toUpperCase() + word.slice(1);
|
|
819
936
|
});
|
|
820
937
|
}
|
|
@@ -850,3 +967,19 @@ function outputHelpIfNecessary(cmd, options) {
|
|
|
850
967
|
}
|
|
851
968
|
}
|
|
852
969
|
}
|
|
970
|
+
|
|
971
|
+
/**
|
|
972
|
+
* Takes an argument an returns its human readable equivalent for help usage.
|
|
973
|
+
*
|
|
974
|
+
* @param {Object} arg
|
|
975
|
+
* @return {String}
|
|
976
|
+
* @api private
|
|
977
|
+
*/
|
|
978
|
+
|
|
979
|
+
function humanReadableArgName(arg) {
|
|
980
|
+
var nameOutput = arg.name + (arg.variadic === true ? '...' : '');
|
|
981
|
+
|
|
982
|
+
return arg.required
|
|
983
|
+
? '<' + nameOutput + '>'
|
|
984
|
+
: '[' + nameOutput + ']'
|
|
985
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commander"
|
|
3
|
-
, "version": "2.
|
|
3
|
+
, "version": "2.5.1"
|
|
4
4
|
, "description": "the complete solution for node.js command-line programs"
|
|
5
|
-
, "keywords": ["command", "option", "parser", "prompt"
|
|
5
|
+
, "keywords": ["command", "option", "parser", "prompt"]
|
|
6
6
|
, "author": "TJ Holowaychuk <tj@vision-media.ca>"
|
|
7
|
-
, "
|
|
7
|
+
, "license": "MIT"
|
|
8
|
+
, "repository": { "type": "git", "url": "https://github.com/tj/commander.js.git" }
|
|
8
9
|
, "devDependencies": { "should": ">= 0.0.1" }
|
|
9
10
|
, "scripts": { "test": "make test" }
|
|
10
11
|
, "main": "index"
|