UNPKG

10.3 kBMarkdownView Raw
1# 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://www.npmjs.org/package/commander)
7[![Join the chat at https://gitter.im/tj/commander.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tj/commander.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
8
9 The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/commander-rb/commander).
10 [API documentation](http://tj.github.com/commander.js/)
11
12
13## Installation
14
15 $ npm install commander --save
16
17## Option parsing
18
19 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.
20
21```js
22#!/usr/bin/env node
23
24/**
25 * Module dependencies.
26 */
27
28var program = require('commander');
29
30program
31 .version('0.1.0')
32 .option('-p, --peppers', 'Add peppers')
33 .option('-P, --pineapple', 'Add pineapple')
34 .option('-b, --bbq-sauce', 'Add bbq sauce')
35 .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
36 .parse(process.argv);
37
38console.log('you ordered a pizza with:');
39if (program.peppers) console.log(' - peppers');
40if (program.pineapple) console.log(' - pineapple');
41if (program.bbqSauce) console.log(' - bbq');
42console.log(' - %s cheese', program.cheese);
43```
44
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.
46
47
48## Coercion
49
50```js
51function range(val) {
52 return val.split('..').map(Number);
53}
54
55function list(val) {
56 return val.split(',');
57}
58
59function collect(val, memo) {
60 memo.push(val);
61 return memo;
62}
63
64function increaseVerbosity(v, total) {
65 return total + 1;
66}
67
68program
69 .version('0.1.0')
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
80console.log(' int: %j', program.integer);
81console.log(' float: %j', program.float);
82console.log(' optional: %j', program.optional);
83program.range = program.range || [];
84console.log(' range: %j..%j', program.range[0], program.range[1]);
85console.log(' list: %j', program.list);
86console.log(' collect: %j', program.collect);
87console.log(' verbosity: %j', program.verbose);
88console.log(' args: %j', program.args);
89```
90
91## Regular Expression
92```js
93program
94 .version('0.1.0')
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
99console.log(' size: %j', program.size);
100console.log(' drink: %j', program.drink);
101```
102
103## Variadic arguments
104
105 The last argument of a command can be variadic, and only the last argument. To make an argument variadic you have to
106 append `...` to the argument name. Here is an example:
107
108```js
109#!/usr/bin/env node
110
111/**
112 * Module dependencies.
113 */
114
115var program = require('commander');
116
117program
118 .version('0.1.0')
119 .command('rmdir <dir> [otherDirs...]')
120 .action(function (dir, otherDirs) {
121 console.log('rmdir %s', dir);
122 if (otherDirs) {
123 otherDirs.forEach(function (oDir) {
124 console.log('rmdir %s', oDir);
125 });
126 }
127 });
128
129program.parse(process.argv);
130```
131
132 An `Array` is used for the value of a variadic argument. This applies to `program.args` as well as the argument passed
133 to your action as demonstrated above.
134
135## Specify the argument syntax
136
137```js
138#!/usr/bin/env node
139
140var program = require('commander');
141
142program
143 .version('0.1.0')
144 .arguments('<cmd> [env]')
145 .action(function (cmd, env) {
146 cmdValue = cmd;
147 envValue = env;
148 });
149
150program.parse(process.argv);
151
152if (typeof cmdValue === 'undefined') {
153 console.error('no command given!');
154 process.exit(1);
155}
156console.log('command:', cmdValue);
157console.log('environment:', envValue || "no environment given");
158```
159Angled brackets (e.g. `<cmd>`) indicate required input. Square brackets (e.g. `[env]`) indicate optional input.
160
161## Git-style sub-commands
162
163```js
164// file: ./examples/pm
165var program = require('commander');
166
167program
168 .version('0.1.0')
169 .command('install [name]', 'install one or more packages')
170 .command('search [query]', 'search with optional query')
171 .command('list', 'list packages installed', {isDefault: true})
172 .parse(process.argv);
173```
174
175When `.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.
176The 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`.
177
178Options can be passed with the call to `.command()`. Specifying `true` for `opts.noHelp` will remove the option from the generated help output. Specifying `true` for `opts.isDefault` will run the subcommand if no other subcommand is specified.
179
180If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
181
182### `--harmony`
183
184You can enable `--harmony` option in two ways:
185* Use `#! /usr/bin/env node --harmony` in the sub-commands scripts. Note some os version don’t support this pattern.
186* 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.
187
188## Automated --help
189
190 The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free:
191
192```
193 $ ./examples/pizza --help
194
195 Usage: pizza [options]
196
197 An application for pizzas ordering
198
199 Options:
200
201 -h, --help output usage information
202 -V, --version output the version number
203 -p, --peppers Add peppers
204 -P, --pineapple Add pineapple
205 -b, --bbq Add bbq sauce
206 -c, --cheese <type> Add the specified type of cheese [marble]
207 -C, --no-cheese You do not want any cheese
208
209```
210
211## Custom help
212
213 You can display arbitrary `-h, --help` information
214 by listening for "--help". Commander will automatically
215 exit once you are done so that the remainder of your program
216 does not execute causing undesired behaviours, for example
217 in the following executable "stuff" will not output when
218 `--help` is used.
219
220```js
221#!/usr/bin/env node
222
223/**
224 * Module dependencies.
225 */
226
227var program = require('commander');
228
229program
230 .version('0.1.0')
231 .option('-f, --foo', 'enable some foo')
232 .option('-b, --bar', 'enable some bar')
233 .option('-B, --baz', 'enable some baz');
234
235// must be before .parse() since
236// node's emit() is immediate
237
238program.on('--help', function(){
239 console.log(' Examples:');
240 console.log('');
241 console.log(' $ custom-help --help');
242 console.log(' $ custom-help -h');
243 console.log('');
244});
245
246program.parse(process.argv);
247
248console.log('stuff');
249```
250
251Yields the following help output when `node script-name.js -h` or `node script-name.js --help` are run:
252
253```
254
255Usage: custom-help [options]
256
257Options:
258
259 -h, --help output usage information
260 -V, --version output the version number
261 -f, --foo enable some foo
262 -b, --bar enable some bar
263 -B, --baz enable some baz
264
265Examples:
266
267 $ custom-help --help
268 $ custom-help -h
269
270```
271
272## .outputHelp(cb)
273
274Output help information without exiting.
275Optional callback cb allows post-processing of help text before it is displayed.
276
277If you want to display help by default (e.g. if no command was provided), you can use something like:
278
279```js
280var program = require('commander');
281var colors = require('colors');
282
283program
284 .version('0.1.0')
285 .command('getstream [url]', 'get stream URL')
286 .parse(process.argv);
287
288 if (!process.argv.slice(2).length) {
289 program.outputHelp(make_red);
290 }
291
292function make_red(txt) {
293 return colors.red(txt); //display the help text in red on the console
294}
295```
296
297## .help(cb)
298
299 Output help information and exit immediately.
300 Optional callback cb allows post-processing of help text before it is displayed.
301
302## Examples
303
304```js
305var program = require('commander');
306
307program
308 .version('0.1.0')
309 .option('-C, --chdir <path>', 'change the working directory')
310 .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
311 .option('-T, --no-tests', 'ignore test hook');
312
313program
314 .command('setup [env]')
315 .description('run setup commands for all envs')
316 .option("-s, --setup_mode [mode]", "Which setup mode to use")
317 .action(function(env, options){
318 var mode = options.setup_mode || "normal";
319 env = env || 'all';
320 console.log('setup for %s env(s) with %s mode', env, mode);
321 });
322
323program
324 .command('exec <cmd>')
325 .alias('ex')
326 .description('execute the given remote cmd')
327 .option("-e, --exec_mode <mode>", "Which exec mode to use")
328 .action(function(cmd, options){
329 console.log('exec "%s" using %s mode', cmd, options.exec_mode);
330 }).on('--help', function() {
331 console.log(' Examples:');
332 console.log();
333 console.log(' $ deploy exec sequential');
334 console.log(' $ deploy exec async');
335 console.log();
336 });
337
338program
339 .command('*')
340 .action(function(env){
341 console.log('deploying "%s"', env);
342 });
343
344program.parse(process.argv);
345```
346
347More Demos can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
348
349## License
350
351MIT