UNPKG

42.8 kBMarkdownView Raw
1# Commander.js
2
3[![Build Status](https://github.com/tj/commander.js/workflows/build/badge.svg)](https://github.com/tj/commander.js/actions?query=workflow%3A%22build%22)
4[![NPM Version](http://img.shields.io/npm/v/commander.svg?style=flat)](https://www.npmjs.org/package/commander)
5[![NPM Downloads](https://img.shields.io/npm/dm/commander.svg?style=flat)](https://npmcharts.com/compare/commander?minimal=true)
6[![Install Size](https://packagephobia.now.sh/badge?p=commander)](https://packagephobia.now.sh/result?p=commander)
7
8The complete solution for [node.js](http://nodejs.org) command-line interfaces.
9
10Read this in other languages: English | [简体中文](./Readme_zh-CN.md)
11
12- [Commander.js](#commanderjs)
13 - [Installation](#installation)
14 - [Quick Start](#quick-start)
15 - [Declaring _program_ variable](#declaring-program-variable)
16 - [Options](#options)
17 - [Common option types, boolean and value](#common-option-types-boolean-and-value)
18 - [Default option value](#default-option-value)
19 - [Other option types, negatable boolean and boolean|value](#other-option-types-negatable-boolean-and-booleanvalue)
20 - [Required option](#required-option)
21 - [Variadic option](#variadic-option)
22 - [Version option](#version-option)
23 - [More configuration](#more-configuration)
24 - [Custom option processing](#custom-option-processing)
25 - [Commands](#commands)
26 - [Command-arguments](#command-arguments)
27 - [More configuration](#more-configuration-1)
28 - [Custom argument processing](#custom-argument-processing)
29 - [Action handler](#action-handler)
30 - [Stand-alone executable (sub)commands](#stand-alone-executable-subcommands)
31 - [Life cycle hooks](#life-cycle-hooks)
32 - [Automated help](#automated-help)
33 - [Custom help](#custom-help)
34 - [Display help after errors](#display-help-after-errors)
35 - [Display help from code](#display-help-from-code)
36 - [.name](#name)
37 - [.usage](#usage)
38 - [.description and .summary](#description-and-summary)
39 - [.helpOption(flags, description)](#helpoptionflags-description)
40 - [.helpCommand()](#helpcommand)
41 - [More configuration](#more-configuration-2)
42 - [Custom event listeners](#custom-event-listeners)
43 - [Bits and pieces](#bits-and-pieces)
44 - [.parse() and .parseAsync()](#parse-and-parseasync)
45 - [Parsing Configuration](#parsing-configuration)
46 - [Legacy options as properties](#legacy-options-as-properties)
47 - [TypeScript](#typescript)
48 - [createCommand()](#createcommand)
49 - [Node options such as `--harmony`](#node-options-such-as---harmony)
50 - [Debugging stand-alone executable subcommands](#debugging-stand-alone-executable-subcommands)
51 - [npm run-script](#npm-run-script)
52 - [Display error](#display-error)
53 - [Override exit and output handling](#override-exit-and-output-handling)
54 - [Additional documentation](#additional-documentation)
55 - [Support](#support)
56 - [Commander for enterprise](#commander-for-enterprise)
57
58For information about terms used in this document see: [terminology](./docs/terminology.md)
59
60## Installation
61
62```sh
63npm install commander
64```
65
66## Quick Start
67
68You write code to describe your command line interface.
69Commander looks after parsing the arguments into options and command-arguments,
70displays usage errors for problems, and implements a help system.
71
72Commander is strict and displays an error for unrecognised options.
73The two most used option types are a boolean option, and an option which takes its value from the following argument.
74
75Example file: [split.js](./examples/split.js)
76
77```js
78const { program } = require('commander');
79
80program
81 .option('--first')
82 .option('-s, --separator <char>');
83
84program.parse();
85
86const options = program.opts();
87const limit = options.first ? 1 : undefined;
88console.log(program.args[0].split(options.separator, limit));
89```
90
91```console
92$ node split.js -s / --fits a/b/c
93error: unknown option '--fits'
94(Did you mean --first?)
95$ node split.js -s / --first a/b/c
96[ 'a' ]
97```
98
99Here is a more complete program using a subcommand and with descriptions for the help. In a multi-command program, you have an action handler for each command (or stand-alone executables for the commands).
100
101Example file: [string-util.js](./examples/string-util.js)
102
103```js
104const { Command } = require('commander');
105const program = new Command();
106
107program
108 .name('string-util')
109 .description('CLI to some JavaScript string utilities')
110 .version('0.8.0');
111
112program.command('split')
113 .description('Split a string into substrings and display as an array')
114 .argument('<string>', 'string to split')
115 .option('--first', 'display just the first substring')
116 .option('-s, --separator <char>', 'separator character', ',')
117 .action((str, options) => {
118 const limit = options.first ? 1 : undefined;
119 console.log(str.split(options.separator, limit));
120 });
121
122program.parse();
123```
124
125```console
126$ node string-util.js help split
127Usage: string-util split [options] <string>
128
129Split a string into substrings and display as an array.
130
131Arguments:
132 string string to split
133
134Options:
135 --first display just the first substring
136 -s, --separator <char> separator character (default: ",")
137 -h, --help display help for command
138
139$ node string-util.js split --separator=/ a/b/c
140[ 'a', 'b', 'c' ]
141```
142
143More samples can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory.
144
145## Declaring _program_ variable
146
147Commander exports a global object which is convenient for quick programs.
148This is used in the examples in this README for brevity.
149
150```js
151// CommonJS (.cjs)
152const { program } = require('commander');
153```
154
155For larger programs which may use commander in multiple ways, including unit testing, it is better to create a local Command object to use.
156
157```js
158// CommonJS (.cjs)
159const { Command } = require('commander');
160const program = new Command();
161```
162
163```js
164// ECMAScript (.mjs)
165import { Command } from 'commander';
166const program = new Command();
167```
168
169```ts
170// TypeScript (.ts)
171import { Command } from 'commander';
172const program = new Command();
173```
174
175## Options
176
177Options are defined with the `.option()` method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar ('|').
178
179The parsed options can be accessed by calling `.opts()` on a `Command` object, and are passed to the action handler.
180
181Multi-word options such as "--template-engine" are camel-cased, becoming `program.opts().templateEngine` etc.
182
183An option and its option-argument can be separated by a space, or combined into the same argument. The option-argument can follow the short option directly or follow an `=` for a long option.
184
185```sh
186serve -p 80
187serve -p80
188serve --port 80
189serve --port=80
190```
191
192You can use `--` to indicate the end of the options, and any remaining arguments will be used without being interpreted.
193
194By default, options on the command line are not positional, and can be specified before or after other arguments.
195
196There are additional related routines for when `.opts()` is not enough:
197
198- `.optsWithGlobals()` returns merged local and global option values
199- `.getOptionValue()` and `.setOptionValue()` work with a single option value
200- `.getOptionValueSource()` and `.setOptionValueWithSource()` include where the option value came from
201
202### Common option types, boolean and value
203
204The two most used option types are a boolean option, and an option which takes its value
205from the following argument (declared with angle brackets like `--expect <value>`). Both are `undefined` unless specified on command line.
206
207Example file: [options-common.js](./examples/options-common.js)
208
209```js
210program
211 .option('-d, --debug', 'output extra debugging')
212 .option('-s, --small', 'small pizza size')
213 .option('-p, --pizza-type <type>', 'flavour of pizza');
214
215program.parse(process.argv);
216
217const options = program.opts();
218if (options.debug) console.log(options);
219console.log('pizza details:');
220if (options.small) console.log('- small pizza size');
221if (options.pizzaType) console.log(`- ${options.pizzaType}`);
222```
223
224```console
225$ pizza-options -p
226error: option '-p, --pizza-type <type>' argument missing
227$ pizza-options -d -s -p vegetarian
228{ debug: true, small: true, pizzaType: 'vegetarian' }
229pizza details:
230- small pizza size
231- vegetarian
232$ pizza-options --pizza-type=cheese
233pizza details:
234- cheese
235```
236
237Multiple boolean short options may be combined following the dash, and may be followed by a single short option taking a value.
238For example `-d -s -p cheese` may be written as `-ds -p cheese` or even `-dsp cheese`.
239
240Options with an expected option-argument are greedy and will consume the following argument whatever the value.
241So `--id -xyz` reads `-xyz` as the option-argument.
242
243`program.parse(arguments)` processes the arguments, leaving any args not consumed by the program options in the `program.args` array. The parameter is optional and defaults to `process.argv`.
244
245### Default option value
246
247You can specify a default value for an option.
248
249Example file: [options-defaults.js](./examples/options-defaults.js)
250
251```js
252program
253 .option('-c, --cheese <type>', 'add the specified type of cheese', 'blue');
254
255program.parse();
256
257console.log(`cheese: ${program.opts().cheese}`);
258```
259
260```console
261$ pizza-options
262cheese: blue
263$ pizza-options --cheese stilton
264cheese: stilton
265```
266
267### Other option types, negatable boolean and boolean|value
268
269You can define a boolean option long name with a leading `no-` to set the option value to false when used.
270Defined alone this also makes the option true by default.
271
272If you define `--foo` first, adding `--no-foo` does not change the default value from what it would
273otherwise be.
274
275Example file: [options-negatable.js](./examples/options-negatable.js)
276
277```js
278program
279 .option('--no-sauce', 'Remove sauce')
280 .option('--cheese <flavour>', 'cheese flavour', 'mozzarella')
281 .option('--no-cheese', 'plain with no cheese')
282 .parse();
283
284const options = program.opts();
285const sauceStr = options.sauce ? 'sauce' : 'no sauce';
286const cheeseStr = (options.cheese === false) ? 'no cheese' : `${options.cheese} cheese`;
287console.log(`You ordered a pizza with ${sauceStr} and ${cheeseStr}`);
288```
289
290```console
291$ pizza-options
292You ordered a pizza with sauce and mozzarella cheese
293$ pizza-options --sauce
294error: unknown option '--sauce'
295$ pizza-options --cheese=blue
296You ordered a pizza with sauce and blue cheese
297$ pizza-options --no-sauce --no-cheese
298You ordered a pizza with no sauce and no cheese
299```
300
301You can specify an option which may be used as a boolean option but may optionally take an option-argument
302(declared with square brackets like `--optional [value]`).
303
304Example file: [options-boolean-or-value.js](./examples/options-boolean-or-value.js)
305
306```js
307program
308 .option('-c, --cheese [type]', 'Add cheese with optional type');
309
310program.parse(process.argv);
311
312const options = program.opts();
313if (options.cheese === undefined) console.log('no cheese');
314else if (options.cheese === true) console.log('add cheese');
315else console.log(`add cheese type ${options.cheese}`);
316```
317
318```console
319$ pizza-options
320no cheese
321$ pizza-options --cheese
322add cheese
323$ pizza-options --cheese mozzarella
324add cheese type mozzarella
325```
326
327Options with an optional option-argument are not greedy and will ignore arguments starting with a dash.
328So `id` behaves as a boolean option for `--id -5`, but you can use a combined form if needed like `--id=-5`.
329
330For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md).
331
332### Required option
333
334You may specify a required (mandatory) option using `.requiredOption()`. The option must have a value after parsing, usually specified on the command line, or perhaps from a default value (say from environment). The method is otherwise the same as `.option()` in format, taking flags and description, and optional default value or custom processing.
335
336Example file: [options-required.js](./examples/options-required.js)
337
338```js
339program
340 .requiredOption('-c, --cheese <type>', 'pizza must have cheese');
341
342program.parse();
343```
344
345```console
346$ pizza
347error: required option '-c, --cheese <type>' not specified
348```
349
350### Variadic option
351
352You may make an option variadic by appending `...` to the value placeholder when declaring the option. On the command line you
353can then specify multiple option-arguments, and the parsed option value will be an array. The extra arguments
354are read until the first argument starting with a dash. The special argument `--` stops option processing entirely. If a value
355is specified in the same argument as the option then no further values are read.
356
357Example file: [options-variadic.js](./examples/options-variadic.js)
358
359```js
360program
361 .option('-n, --number <numbers...>', 'specify numbers')
362 .option('-l, --letter [letters...]', 'specify letters');
363
364program.parse();
365
366console.log('Options: ', program.opts());
367console.log('Remaining arguments: ', program.args);
368```
369
370```console
371$ collect -n 1 2 3 --letter a b c
372Options: { number: [ '1', '2', '3' ], letter: [ 'a', 'b', 'c' ] }
373Remaining arguments: []
374$ collect --letter=A -n80 operand
375Options: { number: [ '80' ], letter: [ 'A' ] }
376Remaining arguments: [ 'operand' ]
377$ collect --letter -n 1 -n 2 3 -- operand
378Options: { number: [ '1', '2', '3' ], letter: true }
379Remaining arguments: [ 'operand' ]
380```
381
382For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md).
383
384### Version option
385
386The optional `version` method adds handling for displaying the command version. The default option flags are `-V` and `--version`, and when present the command prints the version number and exits.
387
388```js
389program.version('0.0.1');
390```
391
392```console
393$ ./examples/pizza -V
3940.0.1
395```
396
397You may change the flags and description by passing additional parameters to the `version` method, using
398the same syntax for flags as the `option` method.
399
400```js
401program.version('0.0.1', '-v, --vers', 'output the current version');
402```
403
404### More configuration
405
406You can add most options using the `.option()` method, but there are some additional features available
407by constructing an `Option` explicitly for less common cases.
408
409Example files: [options-extra.js](./examples/options-extra.js), [options-env.js](./examples/options-env.js), [options-conflicts.js](./examples/options-conflicts.js), [options-implies.js](./examples/options-implies.js)
410
411```js
412program
413 .addOption(new Option('-s, --secret').hideHelp())
414 .addOption(new Option('-t, --timeout <delay>', 'timeout in seconds').default(60, 'one minute'))
415 .addOption(new Option('-d, --drink <size>', 'drink size').choices(['small', 'medium', 'large']))
416 .addOption(new Option('-p, --port <number>', 'port number').env('PORT'))
417 .addOption(new Option('--donate [amount]', 'optional donation in dollars').preset('20').argParser(parseFloat))
418 .addOption(new Option('--disable-server', 'disables the server').conflicts('port'))
419 .addOption(new Option('--free-drink', 'small drink included free ').implies({ drink: 'small' }));
420```
421
422```console
423$ extra --help
424Usage: help [options]
425
426Options:
427 -t, --timeout <delay> timeout in seconds (default: one minute)
428 -d, --drink <size> drink cup size (choices: "small", "medium", "large")
429 -p, --port <number> port number (env: PORT)
430 --donate [amount] optional donation in dollars (preset: "20")
431 --disable-server disables the server
432 --free-drink small drink included free
433 -h, --help display help for command
434
435$ extra --drink huge
436error: option '-d, --drink <size>' argument 'huge' is invalid. Allowed choices are small, medium, large.
437
438$ PORT=80 extra --donate --free-drink
439Options: { timeout: 60, donate: 20, port: '80', freeDrink: true, drink: 'small' }
440
441$ extra --disable-server --port 8000
442error: option '--disable-server' cannot be used with option '-p, --port <number>'
443```
444
445Specify a required (mandatory) option using the `Option` method `.makeOptionMandatory()`. This matches the `Command` method [.requiredOption()](#required-option).
446
447### Custom option processing
448
449You may specify a function to do custom processing of option-arguments. The callback function receives two parameters,
450the user specified option-argument and the previous value for the option. It returns the new value for the option.
451
452This allows you to coerce the option-argument to the desired type, or accumulate values, or do entirely custom processing.
453
454You can optionally specify the default/starting value for the option after the function parameter.
455
456Example file: [options-custom-processing.js](./examples/options-custom-processing.js)
457
458```js
459function myParseInt(value, dummyPrevious) {
460 // parseInt takes a string and a radix
461 const parsedValue = parseInt(value, 10);
462 if (isNaN(parsedValue)) {
463 throw new commander.InvalidArgumentError('Not a number.');
464 }
465 return parsedValue;
466}
467
468function increaseVerbosity(dummyValue, previous) {
469 return previous + 1;
470}
471
472function collect(value, previous) {
473 return previous.concat([value]);
474}
475
476function commaSeparatedList(value, dummyPrevious) {
477 return value.split(',');
478}
479
480program
481 .option('-f, --float <number>', 'float argument', parseFloat)
482 .option('-i, --integer <number>', 'integer argument', myParseInt)
483 .option('-v, --verbose', 'verbosity that can be increased', increaseVerbosity, 0)
484 .option('-c, --collect <value>', 'repeatable value', collect, [])
485 .option('-l, --list <items>', 'comma separated list', commaSeparatedList)
486;
487
488program.parse();
489
490const options = program.opts();
491if (options.float !== undefined) console.log(`float: ${options.float}`);
492if (options.integer !== undefined) console.log(`integer: ${options.integer}`);
493if (options.verbose > 0) console.log(`verbosity: ${options.verbose}`);
494if (options.collect.length > 0) console.log(options.collect);
495if (options.list !== undefined) console.log(options.list);
496```
497
498```console
499$ custom -f 1e2
500float: 100
501$ custom --integer 2
502integer: 2
503$ custom -v -v -v
504verbose: 3
505$ custom -c a -c b -c c
506[ 'a', 'b', 'c' ]
507$ custom --list x,y,z
508[ 'x', 'y', 'z' ]
509```
510
511## Commands
512
513You can specify (sub)commands using `.command()` or `.addCommand()`. There are two ways these can be implemented: using an action handler attached to the command, or as a stand-alone executable file (described in more detail later). The subcommands may be nested ([example](./examples/nestedCommands.js)).
514
515In the first parameter to `.command()` you specify the command name. You may append the command-arguments after the command name, or specify them separately using `.argument()`. The arguments may be `<required>` or `[optional]`, and the last argument may also be `variadic...`.
516
517You can use `.addCommand()` to add an already configured subcommand to the program.
518
519For example:
520
521```js
522// Command implemented using action handler (description is supplied separately to `.command`)
523// Returns new command for configuring.
524program
525 .command('clone <source> [destination]')
526 .description('clone a repository into a newly created directory')
527 .action((source, destination) => {
528 console.log('clone command called');
529 });
530
531// Command implemented using stand-alone executable file, indicated by adding description as second parameter to `.command`.
532// Returns `this` for adding more commands.
533program
534 .command('start <service>', 'start named service')
535 .command('stop [service]', 'stop named service, or all if no name supplied');
536
537// Command prepared separately.
538// Returns `this` for adding more commands.
539program
540 .addCommand(build.makeBuildCommand());
541```
542
543Configuration options can be passed with the call to `.command()` and `.addCommand()`. Specifying `hidden: true` will
544remove the command from the generated help output. Specifying `isDefault: true` will run the subcommand if no other
545subcommand is specified ([example](./examples/defaultCommand.js)).
546
547You can add alternative names for a command with `.alias()`. ([example](./examples/alias.js))
548
549`.command()` automatically copies the inherited settings from the parent command to the newly created subcommand. This is only done during creation, any later setting changes to the parent are not inherited.
550
551For safety, `.addCommand()` does not automatically copy the inherited settings from the parent command. There is a helper routine `.copyInheritedSettings()` for copying the settings when they are wanted.
552
553### Command-arguments
554
555For subcommands, you can specify the argument syntax in the call to `.command()` (as shown above). This
556is the only method usable for subcommands implemented using a stand-alone executable, but for other subcommands
557you can instead use the following method.
558
559To configure a command, you can use `.argument()` to specify each expected command-argument.
560You supply the argument name and an optional description. The argument may be `<required>` or `[optional]`.
561You can specify a default value for an optional command-argument.
562
563Example file: [argument.js](./examples/argument.js)
564
565```js
566program
567 .version('0.1.0')
568 .argument('<username>', 'user to login')
569 .argument('[password]', 'password for user, if required', 'no password given')
570 .action((username, password) => {
571 console.log('username:', username);
572 console.log('password:', password);
573 });
574```
575
576 The last argument of a command can be variadic, and only the last argument. To make an argument variadic you
577 append `...` to the argument name. A variadic argument is passed to the action handler as an array. For example:
578
579```js
580program
581 .version('0.1.0')
582 .command('rmdir')
583 .argument('<dirs...>')
584 .action(function (dirs) {
585 dirs.forEach((dir) => {
586 console.log('rmdir %s', dir);
587 });
588 });
589```
590
591There is a convenience method to add multiple arguments at once, but without descriptions:
592
593```js
594program
595 .arguments('<username> <password>');
596```
597
598#### More configuration
599
600There are some additional features available by constructing an `Argument` explicitly for less common cases.
601
602Example file: [arguments-extra.js](./examples/arguments-extra.js)
603
604```js
605program
606 .addArgument(new commander.Argument('<drink-size>', 'drink cup size').choices(['small', 'medium', 'large']))
607 .addArgument(new commander.Argument('[timeout]', 'timeout in seconds').default(60, 'one minute'))
608```
609
610#### Custom argument processing
611
612You may specify a function to do custom processing of command-arguments (like for option-arguments).
613The callback function receives two parameters, the user specified command-argument and the previous value for the argument.
614It returns the new value for the argument.
615
616The processed argument values are passed to the action handler, and saved as `.processedArgs`.
617
618You can optionally specify the default/starting value for the argument after the function parameter.
619
620Example file: [arguments-custom-processing.js](./examples/arguments-custom-processing.js)
621
622```js
623program
624 .command('add')
625 .argument('<first>', 'integer argument', myParseInt)
626 .argument('[second]', 'integer argument', myParseInt, 1000)
627 .action((first, second) => {
628 console.log(`${first} + ${second} = ${first + second}`);
629 })
630;
631```
632
633### Action handler
634
635The action handler gets passed a parameter for each command-argument you declared, and two additional parameters
636which are the parsed options and the command object itself.
637
638Example file: [thank.js](./examples/thank.js)
639
640```js
641program
642 .argument('<name>')
643 .option('-t, --title <honorific>', 'title to use before name')
644 .option('-d, --debug', 'display some debugging')
645 .action((name, options, command) => {
646 if (options.debug) {
647 console.error('Called %s with options %o', command.name(), options);
648 }
649 const title = options.title ? `${options.title} ` : '';
650 console.log(`Thank-you ${title}${name}`);
651 });
652```
653
654If you prefer, you can work with the command directly and skip declaring the parameters for the action handler. The `this` keyword is set to the running command and can be used from a function expression (but not from an arrow function).
655
656Example file: [action-this.js](./examples/action-this.js)
657
658```js
659program
660 .command('serve')
661 .argument('<script>')
662 .option('-p, --port <number>', 'port number', 80)
663 .action(function() {
664 console.error('Run script %s on port %s', this.args[0], this.opts().port);
665 });
666```
667
668You may supply an `async` action handler, in which case you call `.parseAsync` rather than `.parse`.
669
670```js
671async function run() { /* code goes here */ }
672
673async function main() {
674 program
675 .command('run')
676 .action(run);
677 await program.parseAsync(process.argv);
678}
679```
680
681A command's options and arguments on the command line are validated when the command is used. Any unknown options or missing arguments will be reported as an error. You can suppress the unknown option checks with `.allowUnknownOption()`. By default, it is not an error to
682pass more arguments than declared, but you can make this an error with `.allowExcessArguments(false)`.
683
684### Stand-alone executable (sub)commands
685
686When `.command()` is invoked with a description argument, this tells Commander that you're going to use stand-alone executables for subcommands.
687Commander will search the files in the directory of the entry script for a file with the name combination `command-subcommand`, like `pm-install` or `pm-search` in the example below. The search includes trying common file extensions, like `.js`.
688You may specify a custom name (and path) with the `executableFile` configuration option.
689You may specify a custom search directory for subcommands with `.executableDir()`.
690
691You handle the options for an executable (sub)command in the executable, and don't declare them at the top-level.
692
693Example file: [pm](./examples/pm)
694
695```js
696program
697 .name('pm')
698 .version('0.1.0')
699 .command('install [name]', 'install one or more packages')
700 .command('search [query]', 'search with optional query')
701 .command('update', 'update installed packages', { executableFile: 'myUpdateSubCommand' })
702 .command('list', 'list packages installed', { isDefault: true });
703
704program.parse(process.argv);
705```
706
707If the program is designed to be installed globally, make sure the executables have proper modes, like `755`.
708
709### Life cycle hooks
710
711You can add callback hooks to a command for life cycle events.
712
713Example file: [hook.js](./examples/hook.js)
714
715```js
716program
717 .option('-t, --trace', 'display trace statements for commands')
718 .hook('preAction', (thisCommand, actionCommand) => {
719 if (thisCommand.opts().trace) {
720 console.log(`About to call action handler for subcommand: ${actionCommand.name()}`);
721 console.log('arguments: %O', actionCommand.args);
722 console.log('options: %o', actionCommand.opts());
723 }
724 });
725```
726
727The callback hook can be `async`, in which case you call `.parseAsync` rather than `.parse`. You can add multiple hooks per event.
728
729The supported events are:
730
731| event name | when hook called | callback parameters |
732| :-- | :-- | :-- |
733| `preAction`, `postAction` | before/after action handler for this command and its nested subcommands | `(thisCommand, actionCommand)` |
734| `preSubcommand` | before parsing direct subcommand | `(thisCommand, subcommand)` |
735
736For an overview of the life cycle events see [parsing life cycle and hooks](./docs/parsing-and-hooks.md).
737
738## Automated help
739
740The help information is auto-generated based on the information commander already knows about your program. The default
741help option is `-h,--help`.
742
743Example file: [pizza](./examples/pizza)
744
745```console
746$ node ./examples/pizza --help
747Usage: pizza [options]
748
749An application for pizza ordering
750
751Options:
752 -p, --peppers Add peppers
753 -c, --cheese <type> Add the specified type of cheese (default: "marble")
754 -C, --no-cheese You do not want any cheese
755 -h, --help display help for command
756```
757
758A `help` command is added by default if your command has subcommands. It can be used alone, or with a subcommand name to show
759further help for the subcommand. These are effectively the same if the `shell` program has implicit help:
760
761```sh
762shell help
763shell --help
764
765shell help spawn
766shell spawn --help
767```
768
769Long descriptions are wrapped to fit the available width. (However, a description that includes a line-break followed by whitespace is assumed to be pre-formatted and not wrapped.)
770
771### Custom help
772
773You can add extra text to be displayed along with the built-in help.
774
775Example file: [custom-help](./examples/custom-help)
776
777```js
778program
779 .option('-f, --foo', 'enable some foo');
780
781program.addHelpText('after', `
782
783Example call:
784 $ custom-help --help`);
785```
786
787Yields the following help output:
788
789```Text
790Usage: custom-help [options]
791
792Options:
793 -f, --foo enable some foo
794 -h, --help display help for command
795
796Example call:
797 $ custom-help --help
798```
799
800The positions in order displayed are:
801
802- `beforeAll`: add to the program for a global banner or header
803- `before`: display extra information before built-in help
804- `after`: display extra information after built-in help
805- `afterAll`: add to the program for a global footer (epilog)
806
807The positions "beforeAll" and "afterAll" apply to the command and all its subcommands.
808
809The second parameter can be a string, or a function returning a string. The function is passed a context object for your convenience. The properties are:
810
811- error: a boolean for whether the help is being displayed due to a usage error
812- command: the Command which is displaying the help
813
814### Display help after errors
815
816The default behaviour for usage errors is to just display a short error message.
817You can change the behaviour to show the full help or a custom help message after an error.
818
819```js
820program.showHelpAfterError();
821// or
822program.showHelpAfterError('(add --help for additional information)');
823```
824
825```console
826$ pizza --unknown
827error: unknown option '--unknown'
828(add --help for additional information)
829```
830
831The default behaviour is to suggest correct spelling after an error for an unknown command or option. You
832can disable this.
833
834```js
835program.showSuggestionAfterError(false);
836```
837
838```console
839$ pizza --hepl
840error: unknown option '--hepl'
841(Did you mean --help?)
842```
843
844### Display help from code
845
846`.help()`: display help information and exit immediately. You can optionally pass `{ error: true }` to display on stderr and exit with an error status.
847
848`.outputHelp()`: output help information without exiting. You can optionally pass `{ error: true }` to display on stderr.
849
850`.helpInformation()`: get the built-in command help information as a string for processing or displaying yourself.
851
852### .name
853
854The command name appears in the help, and is also used for locating stand-alone executable subcommands.
855
856You may specify the program name using `.name()` or in the Command constructor. For the program, Commander will
857fall back to using the script name from the full arguments passed into `.parse()`. However, the script name varies
858depending on how your program is launched, so you may wish to specify it explicitly.
859
860```js
861program.name('pizza');
862const pm = new Command('pm');
863```
864
865Subcommands get a name when specified using `.command()`. If you create the subcommand yourself to use with `.addCommand()`,
866then set the name using `.name()` or in the Command constructor.
867
868### .usage
869
870This allows you to customise the usage description in the first line of the help. Given:
871
872```js
873program
874 .name("my-command")
875 .usage("[global options] command")
876```
877
878The help will start with:
879
880```Text
881Usage: my-command [global options] command
882```
883
884### .description and .summary
885
886The description appears in the help for the command. You can optionally supply a shorter
887summary to use when listed as a subcommand of the program.
888
889```js
890program
891 .command("duplicate")
892 .summary("make a copy")
893 .description(`Make a copy of the current project.
894This may require additional disk space.
895 `);
896```
897
898### .helpOption(flags, description)
899
900By default, every command has a help option. You may change the default help flags and description. Pass false to disable the built-in help option.
901
902```js
903program
904 .helpOption('-e, --HELP', 'read more information');
905```
906
907(Or use `.addHelpOption()` to add an option you construct yourself.)
908
909### .helpCommand()
910
911A help command is added by default if your command has subcommands. You can explicitly turn on or off the implicit help command with `.helpCommand(true)` and `.helpCommand(false)`.
912
913You can both turn on and customise the help command by supplying the name and description:
914
915```js
916program.helpCommand('assist [command]', 'show assistance');
917```
918
919(Or use `.addHelpCommand()` to add a command you construct yourself.)
920
921### More configuration
922
923The built-in help is formatted using the Help class.
924You can configure the Help behaviour by modifying data properties and methods using `.configureHelp()`, or by subclassing using `.createHelp()` if you prefer.
925
926The data properties are:
927
928- `helpWidth`: specify the wrap width, useful for unit tests
929- `sortSubcommands`: sort the subcommands alphabetically
930- `sortOptions`: sort the options alphabetically
931- `showGlobalOptions`: show a section with the global options from the parent command(s)
932
933You can override any method on the [Help](./lib/help.js) class. There are methods getting the visible lists of arguments, options, and subcommands. There are methods for formatting the items in the lists, with each item having a _term_ and _description_. Take a look at `.formatHelp()` to see how they are used.
934
935Example file: [configure-help.js](./examples/configure-help.js)
936
937```js
938program.configureHelp({
939 sortSubcommands: true,
940 subcommandTerm: (cmd) => cmd.name() // Just show the name, instead of short usage.
941});
942```
943
944## Custom event listeners
945
946You can execute custom actions by listening to command and option events.
947
948```js
949program.on('option:verbose', function () {
950 process.env.VERBOSE = this.opts().verbose;
951});
952```
953
954## Bits and pieces
955
956### .parse() and .parseAsync()
957
958Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
959
960Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
961
962- `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
963- `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
964- `'user'`: just user arguments
965
966For example:
967
968```js
969program.parse(); // parse process.argv and auto-detect electron and special node flags
970program.parse(process.argv); // assume argv[0] is app and argv[1] is script
971program.parse(['--port', '80'], { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
972```
973
974Use parseAsync instead of parse if any of your action handlers are async.
975
976If you want to parse multiple times, create a new program each time. Calling parse does not clear out any previous state.
977
978### Parsing Configuration
979
980If the default parsing does not suit your needs, there are some behaviours to support other usage patterns.
981
982By default, program options are recognised before and after subcommands. To only look for program options before subcommands, use `.enablePositionalOptions()`. This lets you use
983an option for a different purpose in subcommands.
984
985Example file: [positional-options.js](./examples/positional-options.js)
986
987With positional options, the `-b` is a program option in the first line and a subcommand option in the second line:
988
989```sh
990program -b subcommand
991program subcommand -b
992```
993
994By default, options are recognised before and after command-arguments. To only process options that come
995before the command-arguments, use `.passThroughOptions()`. This lets you pass the arguments and following options through to another program
996without needing to use `--` to end the option processing.
997To use pass through options in a subcommand, the program needs to enable positional options.
998
999Example file: [pass-through-options.js](./examples/pass-through-options.js)
1000
1001With pass through options, the `--port=80` is a program option in the first line and passed through as a command-argument in the second line:
1002
1003```sh
1004program --port=80 arg
1005program arg --port=80
1006```
1007
1008By default, the option processing shows an error for an unknown option. To have an unknown option treated as an ordinary command-argument and continue looking for options, use `.allowUnknownOption()`. This lets you mix known and unknown options.
1009
1010By default, the argument processing does not display an error for more command-arguments than expected.
1011To display an error for excess arguments, use`.allowExcessArguments(false)`.
1012
1013### Legacy options as properties
1014
1015Before Commander 7, the option values were stored as properties on the command.
1016This was convenient to code, but the downside was possible clashes with
1017existing properties of `Command`. You can revert to the old behaviour to run unmodified legacy code by using `.storeOptionsAsProperties()`.
1018
1019```js
1020program
1021 .storeOptionsAsProperties()
1022 .option('-d, --debug')
1023 .action((commandAndOptions) => {
1024 if (commandAndOptions.debug) {
1025 console.error(`Called ${commandAndOptions.name()}`);
1026 }
1027 });
1028```
1029
1030### TypeScript
1031
1032extra-typings: There is an optional project to infer extra type information from the option and argument definitions.
1033This adds strong typing to the options returned by `.opts()` and the parameters to `.action()`.
1034See [commander-js/extra-typings](https://github.com/commander-js/extra-typings) for more.
1035
1036```
1037import { Command } from '@commander-js/extra-typings';
1038```
1039
1040ts-node: If you use `ts-node` and stand-alone executable subcommands written as `.ts` files, you need to call your program through node to get the subcommands called correctly. e.g.
1041
1042```sh
1043node -r ts-node/register pm.ts
1044```
1045
1046### createCommand()
1047
1048This factory function creates a new command. It is exported and may be used instead of using `new`, like:
1049
1050```js
1051const { createCommand } = require('commander');
1052const program = createCommand();
1053```
1054
1055`createCommand` is also a method of the Command object, and creates a new command rather than a subcommand. This gets used internally
1056when creating subcommands using `.command()`, and you may override it to
1057customise the new subcommand (example file [custom-command-class.js](./examples/custom-command-class.js)).
1058
1059### Node options such as `--harmony`
1060
1061You can enable `--harmony` option in two ways:
1062
1063- Use `#! /usr/bin/env node --harmony` in the subcommands scripts. (Note Windows does not support this pattern.)
1064- Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning subcommand process.
1065
1066### Debugging stand-alone executable subcommands
1067
1068An executable subcommand is launched as a separate child process.
1069
1070If you are using the node inspector for [debugging](https://nodejs.org/en/docs/guides/debugging-getting-started/) executable subcommands using `node --inspect` et al.,
1071the inspector port is incremented by 1 for the spawned subcommand.
1072
1073If you are using VSCode to debug executable subcommands you need to set the `"autoAttachChildProcesses": true` flag in your launch.json configuration.
1074
1075### npm run-script
1076
1077By default, when you call your program using run-script, `npm` will parse any options on the command-line and they will not reach your program. Use
1078 `--` to stop the npm option parsing and pass through all the arguments.
1079
1080 The synopsis for [npm run-script](https://docs.npmjs.com/cli/v9/commands/npm-run-script) explicitly shows the `--` for this reason:
1081
1082```console
1083npm run-script <command> [-- <args>]
1084```
1085
1086### Display error
1087
1088This routine is available to invoke the Commander error handling for your own error conditions. (See also the next section about exit handling.)
1089
1090As well as the error message, you can optionally specify the `exitCode` (used with `process.exit`)
1091and `code` (used with `CommanderError`).
1092
1093```js
1094program.error('Password must be longer than four characters');
1095program.error('Custom processing has failed', { exitCode: 2, code: 'my.custom.error' });
1096```
1097
1098### Override exit and output handling
1099
1100By default, Commander calls `process.exit` when it detects errors, or after displaying the help or version. You can override
1101this behaviour and optionally supply a callback. The default override throws a `CommanderError`.
1102
1103The override callback is passed a `CommanderError` with properties `exitCode` number, `code` string, and `message`.
1104Commander expects the callback to terminate the normal program flow, and will call `process.exit` if the callback returns.
1105The normal display of error messages or version or help is not affected by the override which is called after the display.
1106
1107```js
1108program.exitOverride();
1109
1110try {
1111 program.parse(process.argv);
1112} catch (err) {
1113 // custom processing...
1114}
1115```
1116
1117By default, Commander is configured for a command-line application and writes to stdout and stderr.
1118You can modify this behaviour for custom applications. In addition, you can modify the display of error messages.
1119
1120Example file: [configure-output.js](./examples/configure-output.js)
1121
1122```js
1123function errorColor(str) {
1124 // Add ANSI escape codes to display text in red.
1125 return `\x1b[31m${str}\x1b[0m`;
1126}
1127
1128program
1129 .configureOutput({
1130 // Visibly override write routines as example!
1131 writeOut: (str) => process.stdout.write(`[OUT] ${str}`),
1132 writeErr: (str) => process.stdout.write(`[ERR] ${str}`),
1133 // Highlight errors in color.
1134 outputError: (str, write) => write(errorColor(str))
1135 });
1136```
1137
1138### Additional documentation
1139
1140There is more information available about:
1141
1142- [deprecated](./docs/deprecated.md) features still supported for backwards compatibility
1143- [options taking varying arguments](./docs/options-in-depth.md)
1144- [parsing life cycle and hooks](./docs/parsing-and-hooks.md)
1145
1146## Support
1147
1148The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v18.
1149(For older versions of Node.js, use an older version of Commander.)
1150
1151The main forum for free and community support is the project [Issues](https://github.com/tj/commander.js/issues) on GitHub.
1152
1153### Commander for enterprise
1154
1155Available as part of the Tidelift Subscription
1156
1157The maintainers of Commander and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-commander?utm_source=npm-commander&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)