Projekt

Obecné

Profil

Stáhnout (12.5 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
# Commander.js
2
3
4
[![Build Status](https://api.travis-ci.org/tj/commander.js.svg?branch=master)](http://travis-ci.org/tj/commander.js)
5
[![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander)
6
[![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://npmcharts.com/compare/commander?minimal=true)
7
[![Install Size](https://packagephobia.now.sh/badge?p=commander)](https://packagephobia.now.sh/result?p=commander)
8
[![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
9
10
  The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).  
11
  [API documentation](http://tj.github.com/commander.js/)
12
13
14
## Installation
15
16
    $ npm install commander
17
18
## Option parsing
19
20
Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options.
21
22
```js
23
#!/usr/bin/env node
24
25
/**
26
 * Module dependencies.
27
 */
28
29
var program = require('commander');
30
31
program
32
  .version('0.1.0')
33
  .option('-p, --peppers', 'Add peppers')
34
  .option('-P, --pineapple', 'Add pineapple')
35
  .option('-b, --bbq-sauce', 'Add bbq sauce')
36
  .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
37
  .parse(process.argv);
38
39
console.log('you ordered a pizza with:');
40
if (program.peppers) console.log('  - peppers');
41
if (program.pineapple) console.log('  - pineapple');
42
if (program.bbqSauce) console.log('  - bbq');
43
console.log('  - %s cheese', program.cheese);
44
```
45
46
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.
47
48
Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false.
49
50
```js
51
#!/usr/bin/env node
52
53
/**
54
 * Module dependencies.
55
 */
56
57
var program = require('commander');
58
59
program
60
  .option('--no-sauce', 'Remove sauce')
61
  .parse(process.argv);
62
63
console.log('you ordered a pizza');
64
if (program.sauce) console.log('  with sauce');
65
else console.log(' without sauce');
66
```
67
68
To get string arguments from options you will need to use angle brackets <> for required inputs or square brackets [] for optional inputs. 
69
70
e.g. ```.option('-m --myarg [myVar]', 'my super cool description')```
71
72
Then to access the input if it was passed in.
73
74
e.g. ```var myInput = program.myarg```
75
76
**NOTE**: If you pass a argument without using brackets the example above will return true and not the value passed in.
77
78
79
## Version option
80
81
Calling the `version` implicitly adds the `-V` and `--version` options to the command.
82
When either of these options is present, the command prints the version number and exits.
83
84
    $ ./examples/pizza -V
85
    0.0.1
86
87
If you want your program to respond to the `-v` option instead of the `-V` option, simply pass custom flags to the `version` method using the same syntax as the `option` method.
88
89
```js
90
program
91
  .version('0.0.1', '-v, --version')
92
```
93
94
The version flags can be named anything, but the long option is required.
95
96
## Command-specific options
97
98
You can attach options to a command.
99
100
```js
101
#!/usr/bin/env node
102
103
var program = require('commander');
104
105
program
106
  .command('rm <dir>')
107
  .option('-r, --recursive', 'Remove recursively')
108
  .action(function (dir, cmd) {
109
    console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
110
  })
111
112
program.parse(process.argv)
113
```
114
115
A command's options are validated when the command is used. Any unknown options will be reported as an error. However, if an action-based command does not define an action, then the options are not validated.
116
117
## Coercion
118
119
```js
120
function range(val) {
121
  return val.split('..').map(Number);
122
}
123
124
function list(val) {
125
  return val.split(',');
126
}
127
128
function collect(val, memo) {
129
  memo.push(val);
130
  return memo;
131
}
132
133
function increaseVerbosity(v, total) {
134
  return total + 1;
135
}
136
137
program
138
  .version('0.1.0')
139
  .usage('[options] <file ...>')
140
  .option('-i, --integer <n>', 'An integer argument', parseInt)
141
  .option('-f, --float <n>', 'A float argument', parseFloat)
142
  .option('-r, --range <a>..<b>', 'A range', range)
143
  .option('-l, --list <items>', 'A list', list)
144
  .option('-o, --optional [value]', 'An optional value')
145
  .option('-c, --collect [value]', 'A repeatable value', collect, [])
146
  .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
147
  .parse(process.argv);
148
149
console.log(' int: %j', program.integer);
150
console.log(' float: %j', program.float);
151
console.log(' optional: %j', program.optional);
152
program.range = program.range || [];
153
console.log(' range: %j..%j', program.range[0], program.range[1]);
154
console.log(' list: %j', program.list);
155
console.log(' collect: %j', program.collect);
156
console.log(' verbosity: %j', program.verbose);
157
console.log(' args: %j', program.args);
158
```
159
160
## Regular Expression
161
```js
162
program
163
  .version('0.1.0')
164
  .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
165
  .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
166
  .parse(process.argv);
167
168
console.log(' size: %j', program.size);
169
console.log(' drink: %j', program.drink);
170
```
171
172
## Variadic arguments
173
174
 The last argument of a command can be variadic, and only the last argument.  To make an argument variadic you have to
175
 append `...` to the argument name.  Here is an example:
176
177
```js
178
#!/usr/bin/env node
179
180
/**
181
 * Module dependencies.
182
 */
183
184
var program = require('commander');
185
186
program
187
  .version('0.1.0')
188
  .command('rmdir <dir> [otherDirs...]')
189
  .action(function (dir, otherDirs) {
190
    console.log('rmdir %s', dir);
191
    if (otherDirs) {
192
      otherDirs.forEach(function (oDir) {
193
        console.log('rmdir %s', oDir);
194
      });
195
    }
196
  });
197
198
program.parse(process.argv);
199
```
200
201
 An `Array` is used for the value of a variadic argument.  This applies to `program.args` as well as the argument passed
202
 to your action as demonstrated above.
203
204
## Specify the argument syntax
205
206
```js
207
#!/usr/bin/env node
208
209
var program = require('commander');
210
211
program
212
  .version('0.1.0')
213
  .arguments('<cmd> [env]')
214
  .action(function (cmd, env) {
215
     cmdValue = cmd;
216
     envValue = env;
217
  });
218
219
program.parse(process.argv);
220
221
if (typeof cmdValue === 'undefined') {
222
   console.error('no command given!');
223
   process.exit(1);
224
}
225
console.log('command:', cmdValue);
226
console.log('environment:', envValue || "no environment given");
227
```
228
Angled brackets (e.g. `<cmd>`) indicate required input. Square brackets (e.g. `[env]`) indicate optional input.
229
230
## Git-style sub-commands
231
232
```js
233
// file: ./examples/pm
234
var program = require('commander');
235
236
program
237
  .version('0.1.0')
238
  .command('install [name]', 'install one or more packages')
239
  .command('search [query]', 'search with optional query')
240
  .command('list', 'list packages installed', {isDefault: true})
241
  .parse(process.argv);
242
```
243
244
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.  
245
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`.
246
247
Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the subcommand from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
248
249
If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
250
251
### `--harmony`
252
253
You can enable `--harmony` option in two ways:
254
* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version don’t support this pattern.
255
* Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning sub-command process.
256
257
## Automated --help
258
259
 The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
260
261
```  
262
$ ./examples/pizza --help
263
Usage: pizza [options]
264
265
An application for pizzas ordering
266
267
Options:
268
  -h, --help           output usage information
269
  -V, --version        output the version number
270
  -p, --peppers        Add peppers
271
  -P, --pineapple      Add pineapple
272
  -b, --bbq            Add bbq sauce
273
  -c, --cheese <type>  Add the specified type of cheese [marble]
274
  -C, --no-cheese      You do not want any cheese
275
```
276
277
## Custom help
278
279
 You can display arbitrary `-h, --help` information
280
 by listening for "--help". Commander will automatically
281
 exit once you are done so that the remainder of your program
282
 does not execute causing undesired behaviors, for example
283
 in the following executable "stuff" will not output when
284
 `--help` is used.
285
286
```js
287
#!/usr/bin/env node
288
289
/**
290
 * Module dependencies.
291
 */
292
293
var program = require('commander');
294
295
program
296
  .version('0.1.0')
297
  .option('-f, --foo', 'enable some foo')
298
  .option('-b, --bar', 'enable some bar')
299
  .option('-B, --baz', 'enable some baz');
300
301
// must be before .parse() since
302
// node's emit() is immediate
303
304
program.on('--help', function(){
305
  console.log('')
306
  console.log('Examples:');
307
  console.log('  $ custom-help --help');
308
  console.log('  $ custom-help -h');
309
});
310
311
program.parse(process.argv);
312
313
console.log('stuff');
314
```
315
316
Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
317
318
```
319
Usage: custom-help [options]
320
321
Options:
322
  -h, --help     output usage information
323
  -V, --version  output the version number
324
  -f, --foo      enable some foo
325
  -b, --bar      enable some bar
326
  -B, --baz      enable some baz
327
328
Examples:
329
  $ custom-help --help
330
  $ custom-help -h
331
```
332
333
## .outputHelp(cb)
334
335
Output help information without exiting.
336
Optional callback cb allows post-processing of help text before it is displayed.
337
338
If you want to display help by default (e.g. if no command was provided), you can use something like:
339
340
```js
341
var program = require('commander');
342
var colors = require('colors');
343
344
program
345
  .version('0.1.0')
346
  .command('getstream [url]', 'get stream URL')
347
  .parse(process.argv);
348
349
if (!process.argv.slice(2).length) {
350
  program.outputHelp(make_red);
351
}
352
353
function make_red(txt) {
354
  return colors.red(txt); //display the help text in red on the console
355
}
356
```
357
358
## .help(cb)
359
360
  Output help information and exit immediately.
361
  Optional callback cb allows post-processing of help text before it is displayed.
362
363
364
## Custom event listeners
365
 You can execute custom actions by listening to command and option events.
366
367
```js
368
program.on('option:verbose', function () {
369
  process.env.VERBOSE = this.verbose;
370
});
371
372
// error on unknown commands
373
program.on('command:*', function () {
374
  console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '));
375
  process.exit(1);
376
});
377
```
378
379
## Examples
380
381
```js
382
var program = require('commander');
383
384
program
385
  .version('0.1.0')
386
  .option('-C, --chdir <path>', 'change the working directory')
387
  .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
388
  .option('-T, --no-tests', 'ignore test hook');
389
390
program
391
  .command('setup [env]')
392
  .description('run setup commands for all envs')
393
  .option("-s, --setup_mode [mode]", "Which setup mode to use")
394
  .action(function(env, options){
395
    var mode = options.setup_mode || "normal";
396
    env = env || 'all';
397
    console.log('setup for %s env(s) with %s mode', env, mode);
398
  });
399
400
program
401
  .command('exec <cmd>')
402
  .alias('ex')
403
  .description('execute the given remote cmd')
404
  .option("-e, --exec_mode <mode>", "Which exec mode to use")
405
  .action(function(cmd, options){
406
    console.log('exec "%s" using %s mode', cmd, options.exec_mode);
407
  }).on('--help', function() {
408
    console.log('');
409
    console.log('Examples:');
410
    console.log('');
411
    console.log('  $ deploy exec sequential');
412
    console.log('  $ deploy exec async');
413
  });
414
415
program
416
  .command('*')
417
  .action(function(env){
418
    console.log('deploying "%s"', env);
419
  });
420
421
program.parse(process.argv);
422
```
423
424
More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
425
426
## License
427
428
[MIT](https://github.com/tj/commander.js/blob/master/LICENSE)