Readme.md (42324B)
1 # Commander.js 2 3 [](https://github.com/tj/commander.js/actions?query=workflow%3A%22build%22) 4 [](https://www.npmjs.org/package/commander) 5 [](https://npmcharts.com/compare/commander?minimal=true) 6 [](https://packagephobia.now.sh/result?p=commander) 7 8 The complete solution for [node.js](http://nodejs.org) command-line interfaces. 9 10 Read 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 - [.addHelpCommand()](#addhelpcommand) 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 58 For information about terms used in this document see: [terminology](./docs/terminology.md) 59 60 ## Installation 61 62 ```sh 63 npm install commander 64 ``` 65 66 ## Quick Start 67 68 You write code to describe your command line interface. 69 Commander looks after parsing the arguments into options and command-arguments, 70 displays usage errors for problems, and implements a help system. 71 72 Commander is strict and displays an error for unrecognised options. 73 The two most used option types are a boolean option, and an option which takes its value from the following argument. 74 75 Example file: [split.js](./examples/split.js) 76 77 ```js 78 const { program } = require('commander'); 79 80 program 81 .option('--first') 82 .option('-s, --separator <char>'); 83 84 program.parse(); 85 86 const options = program.opts(); 87 const limit = options.first ? 1 : undefined; 88 console.log(program.args[0].split(options.separator, limit)); 89 ``` 90 91 ```console 92 $ node split.js -s / --fits a/b/c 93 error: unknown option '--fits' 94 (Did you mean --first?) 95 $ node split.js -s / --first a/b/c 96 [ 'a' ] 97 ``` 98 99 Here 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 101 Example file: [string-util.js](./examples/string-util.js) 102 103 ```js 104 const { Command } = require('commander'); 105 const program = new Command(); 106 107 program 108 .name('string-util') 109 .description('CLI to some JavaScript string utilities') 110 .version('0.8.0'); 111 112 program.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 122 program.parse(); 123 ``` 124 125 ```console 126 $ node string-util.js help split 127 Usage: string-util split [options] <string> 128 129 Split a string into substrings and display as an array. 130 131 Arguments: 132 string string to split 133 134 Options: 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 143 More samples can be found in the [examples](https://github.com/tj/commander.js/tree/master/examples) directory. 144 145 ## Declaring _program_ variable 146 147 Commander exports a global object which is convenient for quick programs. 148 This is used in the examples in this README for brevity. 149 150 ```js 151 // CommonJS (.cjs) 152 const { program } = require('commander'); 153 ``` 154 155 For 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) 159 const { Command } = require('commander'); 160 const program = new Command(); 161 ``` 162 163 ```js 164 // ECMAScript (.mjs) 165 import { Command } from 'commander'; 166 const program = new Command(); 167 ``` 168 169 ```ts 170 // TypeScript (.ts) 171 import { Command } from 'commander'; 172 const program = new Command(); 173 ``` 174 175 ## Options 176 177 Options 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 179 The parsed options can be accessed by calling `.opts()` on a `Command` object, and are passed to the action handler. 180 181 Multi-word options such as "--template-engine" are camel-cased, becoming `program.opts().templateEngine` etc. 182 183 An 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 186 serve -p 80 187 serve -p80 188 serve --port 80 189 serve --port=80 190 ``` 191 192 You can use `--` to indicate the end of the options, and any remaining arguments will be used without being interpreted. 193 194 By default, options on the command line are not positional, and can be specified before or after other arguments. 195 196 There 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 204 The two most used option types are a boolean option, and an option which takes its value 205 from the following argument (declared with angle brackets like `--expect <value>`). Both are `undefined` unless specified on command line. 206 207 Example file: [options-common.js](./examples/options-common.js) 208 209 ```js 210 program 211 .option('-d, --debug', 'output extra debugging') 212 .option('-s, --small', 'small pizza size') 213 .option('-p, --pizza-type <type>', 'flavour of pizza'); 214 215 program.parse(process.argv); 216 217 const options = program.opts(); 218 if (options.debug) console.log(options); 219 console.log('pizza details:'); 220 if (options.small) console.log('- small pizza size'); 221 if (options.pizzaType) console.log(`- ${options.pizzaType}`); 222 ``` 223 224 ```console 225 $ pizza-options -p 226 error: option '-p, --pizza-type <type>' argument missing 227 $ pizza-options -d -s -p vegetarian 228 { debug: true, small: true, pizzaType: 'vegetarian' } 229 pizza details: 230 - small pizza size 231 - vegetarian 232 $ pizza-options --pizza-type=cheese 233 pizza details: 234 - cheese 235 ``` 236 237 Multiple boolean short options may be combined following the dash, and may be followed by a single short option taking a value. 238 For example `-d -s -p cheese` may be written as `-ds -p cheese` or even `-dsp cheese`. 239 240 Options with an expected option-argument are greedy and will consume the following argument whatever the value. 241 So `--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 247 You can specify a default value for an option. 248 249 Example file: [options-defaults.js](./examples/options-defaults.js) 250 251 ```js 252 program 253 .option('-c, --cheese <type>', 'add the specified type of cheese', 'blue'); 254 255 program.parse(); 256 257 console.log(`cheese: ${program.opts().cheese}`); 258 ``` 259 260 ```console 261 $ pizza-options 262 cheese: blue 263 $ pizza-options --cheese stilton 264 cheese: stilton 265 ``` 266 267 ### Other option types, negatable boolean and boolean|value 268 269 You can define a boolean option long name with a leading `no-` to set the option value to false when used. 270 Defined alone this also makes the option true by default. 271 272 If you define `--foo` first, adding `--no-foo` does not change the default value from what it would 273 otherwise be. 274 275 Example file: [options-negatable.js](./examples/options-negatable.js) 276 277 ```js 278 program 279 .option('--no-sauce', 'Remove sauce') 280 .option('--cheese <flavour>', 'cheese flavour', 'mozzarella') 281 .option('--no-cheese', 'plain with no cheese') 282 .parse(); 283 284 const options = program.opts(); 285 const sauceStr = options.sauce ? 'sauce' : 'no sauce'; 286 const cheeseStr = (options.cheese === false) ? 'no cheese' : `${options.cheese} cheese`; 287 console.log(`You ordered a pizza with ${sauceStr} and ${cheeseStr}`); 288 ``` 289 290 ```console 291 $ pizza-options 292 You ordered a pizza with sauce and mozzarella cheese 293 $ pizza-options --sauce 294 error: unknown option '--sauce' 295 $ pizza-options --cheese=blue 296 You ordered a pizza with sauce and blue cheese 297 $ pizza-options --no-sauce --no-cheese 298 You ordered a pizza with no sauce and no cheese 299 ``` 300 301 You 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 304 Example file: [options-boolean-or-value.js](./examples/options-boolean-or-value.js) 305 306 ```js 307 program 308 .option('-c, --cheese [type]', 'Add cheese with optional type'); 309 310 program.parse(process.argv); 311 312 const options = program.opts(); 313 if (options.cheese === undefined) console.log('no cheese'); 314 else if (options.cheese === true) console.log('add cheese'); 315 else console.log(`add cheese type ${options.cheese}`); 316 ``` 317 318 ```console 319 $ pizza-options 320 no cheese 321 $ pizza-options --cheese 322 add cheese 323 $ pizza-options --cheese mozzarella 324 add cheese type mozzarella 325 ``` 326 327 Options with an optional option-argument are not greedy and will ignore arguments starting with a dash. 328 So `id` behaves as a boolean option for `--id -5`, but you can use a combined form if needed like `--id=-5`. 329 330 For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md). 331 332 ### Required option 333 334 You 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 336 Example file: [options-required.js](./examples/options-required.js) 337 338 ```js 339 program 340 .requiredOption('-c, --cheese <type>', 'pizza must have cheese'); 341 342 program.parse(); 343 ``` 344 345 ```console 346 $ pizza 347 error: required option '-c, --cheese <type>' not specified 348 ``` 349 350 ### Variadic option 351 352 You may make an option variadic by appending `...` to the value placeholder when declaring the option. On the command line you 353 can then specify multiple option-arguments, and the parsed option value will be an array. The extra arguments 354 are read until the first argument starting with a dash. The special argument `--` stops option processing entirely. If a value 355 is specified in the same argument as the option then no further values are read. 356 357 Example file: [options-variadic.js](./examples/options-variadic.js) 358 359 ```js 360 program 361 .option('-n, --number <numbers...>', 'specify numbers') 362 .option('-l, --letter [letters...]', 'specify letters'); 363 364 program.parse(); 365 366 console.log('Options: ', program.opts()); 367 console.log('Remaining arguments: ', program.args); 368 ``` 369 370 ```console 371 $ collect -n 1 2 3 --letter a b c 372 Options: { number: [ '1', '2', '3' ], letter: [ 'a', 'b', 'c' ] } 373 Remaining arguments: [] 374 $ collect --letter=A -n80 operand 375 Options: { number: [ '80' ], letter: [ 'A' ] } 376 Remaining arguments: [ 'operand' ] 377 $ collect --letter -n 1 -n 2 3 -- operand 378 Options: { number: [ '1', '2', '3' ], letter: true } 379 Remaining arguments: [ 'operand' ] 380 ``` 381 382 For information about possible ambiguous cases, see [options taking varying arguments](./docs/options-in-depth.md). 383 384 ### Version option 385 386 The 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 389 program.version('0.0.1'); 390 ``` 391 392 ```console 393 $ ./examples/pizza -V 394 0.0.1 395 ``` 396 397 You may change the flags and description by passing additional parameters to the `version` method, using 398 the same syntax for flags as the `option` method. 399 400 ```js 401 program.version('0.0.1', '-v, --vers', 'output the current version'); 402 ``` 403 404 ### More configuration 405 406 You can add most options using the `.option()` method, but there are some additional features available 407 by constructing an `Option` explicitly for less common cases. 408 409 Example 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 412 program 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 424 Usage: help [options] 425 426 Options: 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 436 error: option '-d, --drink <size>' argument 'huge' is invalid. Allowed choices are small, medium, large. 437 438 $ PORT=80 extra --donate --free-drink 439 Options: { timeout: 60, donate: 20, port: '80', freeDrink: true, drink: 'small' } 440 441 $ extra --disable-server --port 8000 442 error: option '--disable-server' cannot be used with option '-p, --port <number>' 443 ``` 444 445 Specify a required (mandatory) option using the `Option` method `.makeOptionMandatory()`. This matches the `Command` method [.requiredOption()](#required-option). 446 447 ### Custom option processing 448 449 You may specify a function to do custom processing of option-arguments. The callback function receives two parameters, 450 the user specified option-argument and the previous value for the option. It returns the new value for the option. 451 452 This allows you to coerce the option-argument to the desired type, or accumulate values, or do entirely custom processing. 453 454 You can optionally specify the default/starting value for the option after the function parameter. 455 456 Example file: [options-custom-processing.js](./examples/options-custom-processing.js) 457 458 ```js 459 function 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 468 function increaseVerbosity(dummyValue, previous) { 469 return previous + 1; 470 } 471 472 function collect(value, previous) { 473 return previous.concat([value]); 474 } 475 476 function commaSeparatedList(value, dummyPrevious) { 477 return value.split(','); 478 } 479 480 program 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 488 program.parse(); 489 490 const options = program.opts(); 491 if (options.float !== undefined) console.log(`float: ${options.float}`); 492 if (options.integer !== undefined) console.log(`integer: ${options.integer}`); 493 if (options.verbose > 0) console.log(`verbosity: ${options.verbose}`); 494 if (options.collect.length > 0) console.log(options.collect); 495 if (options.list !== undefined) console.log(options.list); 496 ``` 497 498 ```console 499 $ custom -f 1e2 500 float: 100 501 $ custom --integer 2 502 integer: 2 503 $ custom -v -v -v 504 verbose: 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 513 You 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 515 In 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 517 You can use `.addCommand()` to add an already configured subcommand to the program. 518 519 For example: 520 521 ```js 522 // Command implemented using action handler (description is supplied separately to `.command`) 523 // Returns new command for configuring. 524 program 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. 533 program 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. 539 program 540 .addCommand(build.makeBuildCommand()); 541 ``` 542 543 Configuration options can be passed with the call to `.command()` and `.addCommand()`. Specifying `hidden: true` will 544 remove the command from the generated help output. Specifying `isDefault: true` will run the subcommand if no other 545 subcommand is specified ([example](./examples/defaultCommand.js)). 546 547 You 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 551 For 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 555 For subcommands, you can specify the argument syntax in the call to `.command()` (as shown above). This 556 is the only method usable for subcommands implemented using a stand-alone executable, but for other subcommands 557 you can instead use the following method. 558 559 To configure a command, you can use `.argument()` to specify each expected command-argument. 560 You supply the argument name and an optional description. The argument may be `<required>` or `[optional]`. 561 You can specify a default value for an optional command-argument. 562 563 Example file: [argument.js](./examples/argument.js) 564 565 ```js 566 program 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 580 program 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 591 There is a convenience method to add multiple arguments at once, but without descriptions: 592 593 ```js 594 program 595 .arguments('<username> <password>'); 596 ``` 597 598 #### More configuration 599 600 There are some additional features available by constructing an `Argument` explicitly for less common cases. 601 602 Example file: [arguments-extra.js](./examples/arguments-extra.js) 603 604 ```js 605 program 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 612 You may specify a function to do custom processing of command-arguments (like for option-arguments). 613 The callback function receives two parameters, the user specified command-argument and the previous value for the argument. 614 It returns the new value for the argument. 615 616 The processed argument values are passed to the action handler, and saved as `.processedArgs`. 617 618 You can optionally specify the default/starting value for the argument after the function parameter. 619 620 Example file: [arguments-custom-processing.js](./examples/arguments-custom-processing.js) 621 622 ```js 623 program 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 635 The action handler gets passed a parameter for each command-argument you declared, and two additional parameters 636 which are the parsed options and the command object itself. 637 638 Example file: [thank.js](./examples/thank.js) 639 640 ```js 641 program 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 654 If 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 656 Example file: [action-this.js](./examples/action-this.js) 657 658 ```js 659 program 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 668 You may supply an `async` action handler, in which case you call `.parseAsync` rather than `.parse`. 669 670 ```js 671 async function run() { /* code goes here */ } 672 673 async function main() { 674 program 675 .command('run') 676 .action(run); 677 await program.parseAsync(process.argv); 678 } 679 ``` 680 681 A 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 682 pass more arguments than declared, but you can make this an error with `.allowExcessArguments(false)`. 683 684 ### Stand-alone executable (sub)commands 685 686 When `.command()` is invoked with a description argument, this tells Commander that you're going to use stand-alone executables for subcommands. 687 Commander 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`. 688 You may specify a custom name (and path) with the `executableFile` configuration option. 689 You may specify a custom search directory for subcommands with `.executableDir()`. 690 691 You handle the options for an executable (sub)command in the executable, and don't declare them at the top-level. 692 693 Example file: [pm](./examples/pm) 694 695 ```js 696 program 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 704 program.parse(process.argv); 705 ``` 706 707 If the program is designed to be installed globally, make sure the executables have proper modes, like `755`. 708 709 ### Life cycle hooks 710 711 You can add callback hooks to a command for life cycle events. 712 713 Example file: [hook.js](./examples/hook.js) 714 715 ```js 716 program 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 727 The callback hook can be `async`, in which case you call `.parseAsync` rather than `.parse`. You can add multiple hooks per event. 728 729 The 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 736 For an overview of the life cycle events see [parsing life cycle and hooks](./docs/parsing-and-hooks.md). 737 738 ## Automated help 739 740 The help information is auto-generated based on the information commander already knows about your program. The default 741 help option is `-h,--help`. 742 743 Example file: [pizza](./examples/pizza) 744 745 ```console 746 $ node ./examples/pizza --help 747 Usage: pizza [options] 748 749 An application for pizza ordering 750 751 Options: 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 758 A `help` command is added by default if your command has subcommands. It can be used alone, or with a subcommand name to show 759 further help for the subcommand. These are effectively the same if the `shell` program has implicit help: 760 761 ```sh 762 shell help 763 shell --help 764 765 shell help spawn 766 shell spawn --help 767 ``` 768 769 Long 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 773 You can add extra text to be displayed along with the built-in help. 774 775 Example file: [custom-help](./examples/custom-help) 776 777 ```js 778 program 779 .option('-f, --foo', 'enable some foo'); 780 781 program.addHelpText('after', ` 782 783 Example call: 784 $ custom-help --help`); 785 ``` 786 787 Yields the following help output: 788 789 ```Text 790 Usage: custom-help [options] 791 792 Options: 793 -f, --foo enable some foo 794 -h, --help display help for command 795 796 Example call: 797 $ custom-help --help 798 ``` 799 800 The 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 807 The positions "beforeAll" and "afterAll" apply to the command and all its subcommands. 808 809 The 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 816 The default behaviour for usage errors is to just display a short error message. 817 You can change the behaviour to show the full help or a custom help message after an error. 818 819 ```js 820 program.showHelpAfterError(); 821 // or 822 program.showHelpAfterError('(add --help for additional information)'); 823 ``` 824 825 ```console 826 $ pizza --unknown 827 error: unknown option '--unknown' 828 (add --help for additional information) 829 ``` 830 831 The default behaviour is to suggest correct spelling after an error for an unknown command or option. You 832 can disable this. 833 834 ```js 835 program.showSuggestionAfterError(false); 836 ``` 837 838 ```console 839 $ pizza --hepl 840 error: 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 854 The command name appears in the help, and is also used for locating stand-alone executable subcommands. 855 856 You may specify the program name using `.name()` or in the Command constructor. For the program, Commander will 857 fall back to using the script name from the full arguments passed into `.parse()`. However, the script name varies 858 depending on how your program is launched, so you may wish to specify it explicitly. 859 860 ```js 861 program.name('pizza'); 862 const pm = new Command('pm'); 863 ``` 864 865 Subcommands get a name when specified using `.command()`. If you create the subcommand yourself to use with `.addCommand()`, 866 then set the name using `.name()` or in the Command constructor. 867 868 ### .usage 869 870 This allows you to customise the usage description in the first line of the help. Given: 871 872 ```js 873 program 874 .name("my-command") 875 .usage("[global options] command") 876 ``` 877 878 The help will start with: 879 880 ```Text 881 Usage: my-command [global options] command 882 ``` 883 884 ### .description and .summary 885 886 The description appears in the help for the command. You can optionally supply a shorter 887 summary to use when listed as a subcommand of the program. 888 889 ```js 890 program 891 .command("duplicate") 892 .summary("make a copy") 893 .description(`Make a copy of the current project. 894 This may require additional disk space. 895 `); 896 ``` 897 898 ### .helpOption(flags, description) 899 900 By 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 903 program 904 .helpOption('-e, --HELP', 'read more information'); 905 ``` 906 907 ### .addHelpCommand() 908 909 A help command is added by default if your command has subcommands. You can explicitly turn on or off the implicit help command with `.addHelpCommand()` and `.addHelpCommand(false)`. 910 911 You can both turn on and customise the help command by supplying the name and description: 912 913 ```js 914 program.addHelpCommand('assist [command]', 'show assistance'); 915 ``` 916 917 ### More configuration 918 919 The built-in help is formatted using the Help class. 920 You can configure the Help behaviour by modifying data properties and methods using `.configureHelp()`, or by subclassing using `.createHelp()` if you prefer. 921 922 The data properties are: 923 924 - `helpWidth`: specify the wrap width, useful for unit tests 925 - `sortSubcommands`: sort the subcommands alphabetically 926 - `sortOptions`: sort the options alphabetically 927 - `showGlobalOptions`: show a section with the global options from the parent command(s) 928 929 You 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. 930 931 Example file: [configure-help.js](./examples/configure-help.js) 932 933 ```js 934 program.configureHelp({ 935 sortSubcommands: true, 936 subcommandTerm: (cmd) => cmd.name() // Just show the name, instead of short usage. 937 }); 938 ``` 939 940 ## Custom event listeners 941 942 You can execute custom actions by listening to command and option events. 943 944 ```js 945 program.on('option:verbose', function () { 946 process.env.VERBOSE = this.opts().verbose; 947 }); 948 ``` 949 950 ## Bits and pieces 951 952 ### .parse() and .parseAsync() 953 954 The first argument to `.parse` is the array of strings to parse. You may omit the parameter to implicitly use `process.argv`. 955 956 If the arguments follow different conventions than node you can pass a `from` option in the second parameter: 957 958 - 'node': default, `argv[0]` is the application and `argv[1]` is the script being run, with user parameters after that 959 - 'electron': `argv[1]` varies depending on whether the electron application is packaged 960 - 'user': all of the arguments from the user 961 962 For example: 963 964 ```js 965 program.parse(process.argv); // Explicit, node conventions 966 program.parse(); // Implicit, and auto-detect electron 967 program.parse(['-f', 'filename'], { from: 'user' }); 968 ``` 969 970 ### Parsing Configuration 971 972 If the default parsing does not suit your needs, there are some behaviours to support other usage patterns. 973 974 By default, program options are recognised before and after subcommands. To only look for program options before subcommands, use `.enablePositionalOptions()`. This lets you use 975 an option for a different purpose in subcommands. 976 977 Example file: [positional-options.js](./examples/positional-options.js) 978 979 With positional options, the `-b` is a program option in the first line and a subcommand option in the second line: 980 981 ```sh 982 program -b subcommand 983 program subcommand -b 984 ``` 985 986 By default, options are recognised before and after command-arguments. To only process options that come 987 before the command-arguments, use `.passThroughOptions()`. This lets you pass the arguments and following options through to another program 988 without needing to use `--` to end the option processing. 989 To use pass through options in a subcommand, the program needs to enable positional options. 990 991 Example file: [pass-through-options.js](./examples/pass-through-options.js) 992 993 With 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: 994 995 ```sh 996 program --port=80 arg 997 program arg --port=80 998 ``` 999 1000 By 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. 1001 1002 By default, the argument processing does not display an error for more command-arguments than expected. 1003 To display an error for excess arguments, use`.allowExcessArguments(false)`. 1004 1005 ### Legacy options as properties 1006 1007 Before Commander 7, the option values were stored as properties on the command. 1008 This was convenient to code, but the downside was possible clashes with 1009 existing properties of `Command`. You can revert to the old behaviour to run unmodified legacy code by using `.storeOptionsAsProperties()`. 1010 1011 ```js 1012 program 1013 .storeOptionsAsProperties() 1014 .option('-d, --debug') 1015 .action((commandAndOptions) => { 1016 if (commandAndOptions.debug) { 1017 console.error(`Called ${commandAndOptions.name()}`); 1018 } 1019 }); 1020 ``` 1021 1022 ### TypeScript 1023 1024 extra-typings: There is an optional project to infer extra type information from the option and argument definitions. 1025 This adds strong typing to the options returned by `.opts()` and the parameters to `.action()`. 1026 See [commander-js/extra-typings](https://github.com/commander-js/extra-typings) for more. 1027 1028 ``` 1029 import { Command } from '@commander-js/extra-typings'; 1030 ``` 1031 1032 ts-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. 1033 1034 ```sh 1035 node -r ts-node/register pm.ts 1036 ``` 1037 1038 ### createCommand() 1039 1040 This factory function creates a new command. It is exported and may be used instead of using `new`, like: 1041 1042 ```js 1043 const { createCommand } = require('commander'); 1044 const program = createCommand(); 1045 ``` 1046 1047 `createCommand` is also a method of the Command object, and creates a new command rather than a subcommand. This gets used internally 1048 when creating subcommands using `.command()`, and you may override it to 1049 customise the new subcommand (example file [custom-command-class.js](./examples/custom-command-class.js)). 1050 1051 ### Node options such as `--harmony` 1052 1053 You can enable `--harmony` option in two ways: 1054 1055 - Use `#! /usr/bin/env node --harmony` in the subcommands scripts. (Note Windows does not support this pattern.) 1056 - Use the `--harmony` option when call the command, like `node --harmony examples/pm publish`. The `--harmony` option will be preserved when spawning subcommand process. 1057 1058 ### Debugging stand-alone executable subcommands 1059 1060 An executable subcommand is launched as a separate child process. 1061 1062 If you are using the node inspector for [debugging](https://nodejs.org/en/docs/guides/debugging-getting-started/) executable subcommands using `node --inspect` et al., 1063 the inspector port is incremented by 1 for the spawned subcommand. 1064 1065 If you are using VSCode to debug executable subcommands you need to set the `"autoAttachChildProcesses": true` flag in your launch.json configuration. 1066 1067 ### npm run-script 1068 1069 By 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 1070 `--` to stop the npm option parsing and pass through all the arguments. 1071 1072 The synopsis for [npm run-script](https://docs.npmjs.com/cli/v9/commands/npm-run-script) explicitly shows the `--` for this reason: 1073 1074 ```console 1075 npm run-script <command> [-- <args>] 1076 ``` 1077 1078 ### Display error 1079 1080 This routine is available to invoke the Commander error handling for your own error conditions. (See also the next section about exit handling.) 1081 1082 As well as the error message, you can optionally specify the `exitCode` (used with `process.exit`) 1083 and `code` (used with `CommanderError`). 1084 1085 ```js 1086 program.error('Password must be longer than four characters'); 1087 program.error('Custom processing has failed', { exitCode: 2, code: 'my.custom.error' }); 1088 ``` 1089 1090 ### Override exit and output handling 1091 1092 By default, Commander calls `process.exit` when it detects errors, or after displaying the help or version. You can override 1093 this behaviour and optionally supply a callback. The default override throws a `CommanderError`. 1094 1095 The override callback is passed a `CommanderError` with properties `exitCode` number, `code` string, and `message`. The default override behaviour is to throw the error, except for async handling of executable subcommand completion which carries on. The normal display of error messages or version or help 1096 is not affected by the override which is called after the display. 1097 1098 ```js 1099 program.exitOverride(); 1100 1101 try { 1102 program.parse(process.argv); 1103 } catch (err) { 1104 // custom processing... 1105 } 1106 ``` 1107 1108 By default, Commander is configured for a command-line application and writes to stdout and stderr. 1109 You can modify this behaviour for custom applications. In addition, you can modify the display of error messages. 1110 1111 Example file: [configure-output.js](./examples/configure-output.js) 1112 1113 ```js 1114 function errorColor(str) { 1115 // Add ANSI escape codes to display text in red. 1116 return `\x1b[31m${str}\x1b[0m`; 1117 } 1118 1119 program 1120 .configureOutput({ 1121 // Visibly override write routines as example! 1122 writeOut: (str) => process.stdout.write(`[OUT] ${str}`), 1123 writeErr: (str) => process.stdout.write(`[ERR] ${str}`), 1124 // Highlight errors in color. 1125 outputError: (str, write) => write(errorColor(str)) 1126 }); 1127 ``` 1128 1129 ### Additional documentation 1130 1131 There is more information available about: 1132 1133 - [deprecated](./docs/deprecated.md) features still supported for backwards compatibility 1134 - [options taking varying arguments](./docs/options-in-depth.md) 1135 - [parsing life cycle and hooks](./docs/parsing-and-hooks.md) 1136 1137 ## Support 1138 1139 The current version of Commander is fully supported on Long Term Support versions of Node.js, and requires at least v16. 1140 (For older versions of Node.js, use an older version of Commander.) 1141 1142 The main forum for free and community support is the project [Issues](https://github.com/tj/commander.js/issues) on GitHub. 1143 1144 ### Commander for enterprise 1145 1146 Available as part of the Tidelift Subscription 1147 1148 The 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)