1 A light, featureful and explicit option parsing library for node.js.
3 [Why another one? See below](#why). tl;dr: The others I've tried are one of
4 too loosey goosey (not explicit), too big/too many deps, or ill specified.
7 Follow <a href="https://twitter.com/intent/user?screen_name=trentmick" target="_blank">@trentmick</a>
8 for updates to node-dashdash.
18 var dashdash = require('dashdash');
20 // Specify the options. Minimally `name` (or `names`) and `type`
21 // must be given for each.
24 // `names` or a single `name`. First element is the `opts.KEY`.
26 // See "Option specs" below for types.
28 help: 'Print this help and exit.'
32 // Shortcut form. As called it infers `process.argv`. See below for
33 // the longer form to use methods like `.help()` on the Parser object.
34 var opts = dashdash.parse({options: options});
36 console.log("opts:", opts);
37 console.log("args:", opts._args);
43 A more realistic [starter script "foo.js"](./examples/foo.js) is as follows.
44 This also shows using `parser.help()` for formatted option help.
47 var dashdash = require('./lib/dashdash');
53 help: 'Print tool version and exit.'
58 help: 'Print this help and exit.'
61 names: ['verbose', 'v'],
63 help: 'Verbose output. Use multiple times for more verbose.'
68 help: 'File to process',
73 var parser = dashdash.createParser({options: options});
75 var opts = parser.parse(process.argv);
77 console.error('foo: error: %s', e.message);
81 console.log("# opts:", opts);
82 console.log("# args:", opts._args);
84 // Use `parser.help()` for formatted options help.
86 var help = parser.help({includeEnv: true}).trimRight();
87 console.log('usage: node foo.js [OPTIONS]\n'
97 Some example output from this script (foo.js):
101 # opts: { help: true,
102 _order: [ { name: 'help', value: true, from: 'argv' } ],
105 usage: node foo.js [OPTIONS]
107 --version Print tool version and exit.
108 -h, --help Print this help and exit.
109 -v, --verbose Verbose output. Use multiple times for more verbose.
110 -f FILE, --file=FILE File to process
113 # opts: { verbose: [ true ],
114 _order: [ { name: 'verbose', value: true, from: 'argv' } ],
118 $ node foo.js --version arg1
119 # opts: { version: true,
120 _order: [ { name: 'version', value: true, from: 'argv' } ],
124 $ node foo.js -f bar.txt
125 # opts: { file: 'bar.txt',
126 _order: [ { name: 'file', value: 'bar.txt', from: 'argv' } ],
130 $ node foo.js -vvv --file=blah
131 # opts: { verbose: [ true, true, true ],
134 [ { name: 'verbose', value: true, from: 'argv' },
135 { name: 'verbose', value: true, from: 'argv' },
136 { name: 'verbose', value: true, from: 'argv' },
137 { name: 'file', value: 'blah', from: 'argv' } ],
143 See the ["examples"](examples/) dir for a number of starter examples using
144 some of dashdash's features.
147 # Environment variable integration
149 If you want to allow environment variables to specify options to your tool,
150 dashdash makes this easy. We can change the 'verbose' option in the example
151 above to include an 'env' field:
155 names: ['verbose', 'v'],
157 env: 'FOO_VERBOSE', // <--- add this line
158 help: 'Verbose output. Use multiple times for more verbose.'
162 then the **"FOO_VERBOSE" environment variable** can be used to set this
166 $ FOO_VERBOSE=1 node foo.js
167 # opts: { verbose: [ true ],
168 _order: [ { name: 'verbose', value: true, from: 'env' } ],
173 Boolean options will interpret the empty string as unset, '0' as false
174 and anything else as true.
177 $ FOO_VERBOSE= node examples/foo.js # not set
178 # opts: { _order: [], _args: [] }
181 $ FOO_VERBOSE=0 node examples/foo.js # '0' is false
182 # opts: { verbose: [ false ],
183 _order: [ { key: 'verbose', value: false, from: 'env' } ],
187 $ FOO_VERBOSE=1 node examples/foo.js # true
188 # opts: { verbose: [ true ],
189 _order: [ { key: 'verbose', value: true, from: 'env' } ],
193 $ FOO_VERBOSE=boogabooga node examples/foo.js # true
194 # opts: { verbose: [ true ],
195 _order: [ { key: 'verbose', value: true, from: 'env' } ],
200 Non-booleans can be used as well. Strings:
203 $ FOO_FILE=data.txt node examples/foo.js
204 # opts: { file: 'data.txt',
205 _order: [ { key: 'file', value: 'data.txt', from: 'env' } ],
213 $ FOO_TIMEOUT=5000 node examples/foo.js
214 # opts: { timeout: 5000,
215 _order: [ { key: 'timeout', value: 5000, from: 'env' } ],
219 $ FOO_TIMEOUT=blarg node examples/foo.js
220 foo: error: arg for "FOO_TIMEOUT" is not a positive integer: "blarg"
223 With the `includeEnv: true` config to `parser.help()` the environment
224 variable can also be included in **help output**:
226 usage: node foo.js [OPTIONS]
228 --version Print tool version and exit.
229 -h, --help Print this help and exit.
230 -v, --verbose Verbose output. Use multiple times for more verbose.
231 Environment: FOO_VERBOSE=1
232 -f FILE, --file=FILE File to process
237 Dashdash provides a simple way to create a Bash completion file that you
238 can place in your "bash_completion.d" directory -- sometimes that is
239 "/usr/local/etc/bash_completion.d/"). Features:
241 - Support for short and long opts
242 - Support for knowing which options take arguments
243 - Support for subcommands (e.g. 'git log <TAB>' to show just options for the
245 [node-cmdln](https://github.com/trentm/node-cmdln#bash-completion) for
246 how to integrate that.
247 - Does the right thing with "--" to stop options.
248 - Custom optarg and arg types for custom completions.
250 Dashdash will return bash completion file content given a parser instance:
252 var parser = dashdash.createParser({options: options});
253 console.log( parser.bashCompletion({name: 'mycli'}) );
255 or directly from a `options` array of options specs:
257 var code = dashdash.bashCompletionFromOptions({
262 Write that content to "/usr/local/etc/bash_completion.d/mycli" and you will
263 have Bash completions for `mycli`. Alternatively you can write it to
264 any file (e.g. "~/.bashrc") and source it.
266 You could add a `--completion` hidden option to your tool that emits the
267 completion content and document for your users to call that to install
270 See [examples/ddcompletion.js](examples/ddcompletion.js) for a complete
271 example, including how one can define bash functions for completion of custom
272 option types. Also see [node-cmdln](https://github.com/trentm/node-cmdln) for
273 how it uses this for Bash completion for full multi-subcommand tools.
275 - TODO: document specExtra
276 - TODO: document includeHidden
277 - TODO: document custom types, `function complete\_FOO` guide, completionType
278 - TODO: document argtypes
283 Parser construction (i.e. `dashdash.createParser(CONFIG)`) takes the
286 - `options` (Array of option specs). Required. See the
287 [Option specs](#option-specs) section below.
289 - `interspersed` (Boolean). Optional. Default is true. If true this allows
290 interspersed arguments and options. I.e.:
292 node ./tool.js -v arg1 arg2 -h # '-h' is after interspersed args
294 Set it to false to have '-h' **not** get parsed as an option in the above
297 - `allowUnknown` (Boolean). Optional. Default is false. If false, this causes
298 unknown arguments to throw an error. I.e.:
300 node ./tool.js -v arg1 --afe8asefksjefhas
302 Set it to true to treat the unknown option as a positional
305 **Caveat**: When a shortopt group, such as `-xaz` contains a mix of
306 known and unknown options, the *entire* group is passed through
307 unmolested as a positional argument.
309 Consider if you have a known short option `-a`, and parse the
310 following command line:
314 where `-x` and `-z` are unknown. There are multiple ways to
317 1. `-x` takes a value: `{x: 'az'}`
318 2. `-x` and `-z` are both booleans: `{x:true,a:true,z:true}`
320 Since dashdash does not know what `-x` and `-z` are, it can't know
321 if you'd prefer to receive `{a:true,_args:['-x','-z']}` or
322 `{x:'az'}`, or `{_args:['-xaz']}`. Leaving the positional arg unprocessed
323 is the easiest mistake for the user to recover from.
328 Example using all fields (required fields are noted):
332 names: ['file', 'f'], // Required (one of `names` or `name`).
333 type: 'string', // Required.
334 completionType: 'filename',
336 help: 'Config file to load before running "mytool"',
339 default: path.resolve(process.env.HOME, '.mytoolrc')
343 Each option spec in the `options` array must/can have the following fields:
345 - `name` (String) or `names` (Array). Required. These give the option name
346 and aliases. The first name (if more than one given) is the key for the
347 parsed `opts` object.
349 - `type` (String). Required. One of:
356 - date (epoch seconds, e.g. 1396031701, or ISO 8601 format
357 `YYYY-MM-DD[THH:MM:SS[.sss][Z]]`, e.g. "2014-03-28T18:35:01.489Z")
362 - arrayOfPositiveInteger
365 FWIW, these names attempt to match with asserts on
366 [assert-plus](https://github.com/mcavage/node-assert-plus).
367 You can add your own custom option types with `dashdash.addOptionType`.
370 - `completionType` (String). Optional. This is used for [Bash
371 completion](#bash-completion) for an option argument. If not specified,
372 then the value of `type` is used. Any string may be specified, but only the
373 following values have meaning:
375 - `none`: Provide no completions.
376 - `file`: Bash's default completion (i.e. `complete -o default`), which
378 - *Any string FOO for which a `function complete_FOO` Bash function is
379 defined.* This is for custom completions for a given tool. Typically
380 these custom functions are provided in the `specExtra` argument to
381 `dashdash.bashCompletionFromOptions()`. See
382 ["examples/ddcompletion.js"](examples/ddcompletion.js) for an example.
384 - `env` (String or Array of String). Optional. An environment variable name
385 (or names) that can be used as a fallback for this option. For example,
386 given a "foo.js" like this:
388 var options = [{names: ['dry-run', 'n'], env: 'FOO_DRY_RUN'}];
389 var opts = dashdash.parse({options: options});
391 Both `node foo.js --dry-run` and `FOO_DRY_RUN=1 node foo.js` would result
392 in `opts.dry_run = true`.
394 An environment variable is only used as a fallback, i.e. it is ignored if
395 the associated option is given in `argv`.
397 - `help` (String). Optional. Used for `parser.help()` output.
399 - `helpArg` (String). Optional. Used in help output as the placeholder for
400 the option argument, e.g. the "PATH" in:
403 -f PATH, --file=PATH File to process
406 - `helpWrap` (Boolean). Optional, default true. Set this to `false` to have
407 that option's `help` *not* be text wrapped in `<parser>.help()` output.
409 - `default`. Optional. A default value used for this option, if the
410 option isn't specified in argv.
412 - `hidden` (Boolean). Optional, default false. If true, help output will not
413 include this option. See also the `includeHidden` option to
414 `bashCompletionFromOptions()` for [Bash completion](#bash-completion).
417 # Option group headings
419 You can add headings between option specs in the `options` array. To do so,
420 simply add an object with only a `group` property -- the string to print as
421 the heading for the subsequent options in the array. For example:
426 group: 'Armament Options'
429 names: [ 'weapon', 'w' ],
433 group: 'General Options'
436 names: [ 'help', 'h' ],
443 Note: You can use an empty string, `{group: ''}`, to get a blank line in help
444 output between groups of options.
449 The `parser.help(...)` function is configurable as follows:
453 ^^ -w WEAPON, --weapon=WEAPON Weapon with which to crush. One of: |
454 / sword, spear, maul |
456 / -h, --help Print this help and exit. |
458 \ `-- indent `-- helpCol maxCol ---'
461 - `indent` (Number or String). Default 4. Set to a number (for that many
462 spaces) or a string for the literal indent.
463 - `headingIndent` (Number or String). Default half length of `indent`. Set to
464 a number (for that many spaces) or a string for the literal indent. This
465 indent applies to group heading lines, between normal option lines.
466 - `nameSort` (String). Default is 'length'. By default the names are
467 sorted to put the short opts first (i.e. '-h, --help' preferred
468 to '--help, -h'). Set to 'none' to not do this sorting.
469 - `maxCol` (Number). Default 80. Note that reflow is just done on whitespace
470 so a long token in the option help can overflow maxCol.
471 - `helpCol` (Number). If not set a reasonable value will be determined
472 between `minHelpCol` and `maxHelpCol`.
473 - `minHelpCol` (Number). Default 20.
474 - `maxHelpCol` (Number). Default 40.
475 - `helpWrap` (Boolean). Default true. Set to `false` to have option `help`
476 strings *not* be textwrapped to the helpCol..maxCol range.
477 - `includeEnv` (Boolean). Default false. If the option has associated
478 environment variables (via the `env` option spec attribute), then
479 append mentioned of those envvars to the help string.
480 - `includeDefault` (Boolean). Default false. If the option has a default value
481 (via the `default` option spec attribute, or a default on the option's type),
482 then a "Default: VALUE" string will be appended to the help string.
485 # Custom option types
487 Dashdash includes a good starter set of option types that it will parse for
488 you. However, you can add your own via:
490 var dashdash = require('dashdash');
491 dashdash.addOptionType({
495 parseArg: function (option, optstr, arg) {
498 array: false, // optional
499 arrayFlatten: false, // optional
500 default: ..., // optional
501 completionType: ... // optional
504 For example, a simple option type that accepts 'yes', 'y', 'no' or 'n' as
505 a boolean argument would look like:
507 var dashdash = require('dashdash');
509 function parseYesNo(option, optstr, arg) {
510 var argLower = arg.toLowerCase()
511 if (~['yes', 'y'].indexOf(argLower)) {
513 } else if (~['no', 'n'].indexOf(argLower)) {
516 throw new Error(format(
517 'arg for "%s" is not "yes" or "no": "%s"',
522 dashdash.addOptionType({
530 {names: ['answer', 'a'], type: 'yesno'}
532 var opts = dashdash.parse({options: options});
534 See "examples/custom-option-\*.js" for other examples.
535 See the `addOptionType` block comment in "lib/dashdash.js" for more details.
536 Please let me know [with an
537 issue](https://github.com/trentm/node-dashdash/issues/new) if you write a
538 generally useful one.
544 Why another node.js option parsing lib?
546 - `nopt` really is just for "tools like npm". Implicit opts (e.g. '--no-foo'
547 works for every '--foo'). Can't disable abbreviated opts. Can't do multiple
548 usages of same opt, e.g. '-vvv' (I think). Can't do grouped short opts.
550 - `optimist` has surprise interpretation of options (at least to me).
551 Implicit opts mean ambiguities and poor error handling for fat-fingering.
552 `process.exit` calls makes it hard to use as a libary.
554 - `optparse` Incomplete docs. Is this an attempted clone of Python's `optparse`.
555 Not clear. Some divergence. `parser.on("name", ...)` API is weird.
557 - `argparse` Dep on underscore. No thanks just for option processing.
558 `find lib | wc -l` -> `26`. Overkill.
559 Argparse is a bit different anyway. Not sure I want that.
561 - `posix-getopt` No type validation. Though that isn't a killer. AFAIK can't
562 have a long opt without a short alias. I.e. no `getopt_long` semantics.
563 Also, no whizbang features like generated help output.
565 - ["commander.js"](https://github.com/visionmedia/commander.js): I wrote
566 [a critique](http://trentm.com/2014/01/a-critique-of-commander-for-nodejs.html)
567 a while back. It seems fine, but last I checked had
568 [an outstanding bug](https://github.com/visionmedia/commander.js/pull/121)
569 that would prevent me from using it.
574 MIT. See LICENSE.txt.