Caporal
A full-featured framework for building command line applications (cli) with node.js, including help generation, colored output, verbosity control, custom logger, coercion and casting, typos suggestions, and auto-complete for bash/zsh/fish.
Install
Simply add Caporal as a dependency:
$ npm install caporal # Or if you are using yarn (https://yarnpkg.com/lang/en/) $ yarn add caporal
Glossary
- Program: a cli app that you can build using Caporal
- Command: a command within your program. A program may have multiple commands.
- Argument: a command may have one or more arguments passed after the command.
- Options: a command may have one or more options passed after (or before) arguments.
Angled brackets (e.g. <item>
) indicate required input. Square brackets (e.g. [env]
) indicate optional input.
Examples
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' // you specify arguments using .argument() // 'app' is required, 'env' is optional // you specify options using .option() // if --tail is passed, its value is required action { // args and options are objects // args = {"app": "myapp", "env": "production"} // options = {"tail" : 100} }; prog; // ./myprog deploy myapp production --tail 100
Or else if you prefer typescript
#!/usr/bin/env node;prog version'1.0.0' // you specify arguments using .argument() // 'app' is required, 'env' is optional // you specify options using .option() // if --tail is passed, its value is required action { // args and options are objects // args = {"app": "myapp", "env": "production"} // options = {"tail" : 100} }; prog; // ./myprog deploy myapp production --tail 100
Variadic arguments
You can use ...
to indicate variadic arguments. In that case, the resulted value will be an array.
Note: Only the last argument of a command can be variadic !
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' // 'app' and 'env' are required // and you can pass additional environments action { console; // { // "app": "myapp", // "env": "production", // "otherEnv": ["google", "azure"] // } }; prog; // ./myprog deploy myapp production aws google azure
Simple program (single command)
For a very simple program with just one command, you can omit the .command() call:
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' description'A simple program that says "biiiip"' action { logger }; prog;
Programmatic Caporal usage
You can pass arguments and options directly to Caporal API.
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { logger; logger; // { // "app": "myapp", // "env": "production" // } // { // "howMuch": 2 // } };prog;
Logging
Inside your action(), use the logger argument (third one) to log informations.
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { // Available methods: // - logger.debug('message') // - logger.info('message') or logger.log('level', 'message') // - logger.warn('message') // - logger.error('message') logger; }; prog;
Logging levels
The default logging level is 'info'. The predefined options can be used to change the logging level:
-v, --verbose
: Set the logging level to 'debug' so debug() logs will be output.--quiet, --silent
: Set the logging level to 'warn' so only warn() and error() logs will be output.
Custom logger
Caporal uses winston
for logging. You can provide your own winston-compatible logger using .logger()
the following way:
#!/usr/bin/env nodeconst prog = ;const myLogger = ;prog version'1.0.0' action { logger; }; prog;
-v, --verbose
: Set the logging level to 'debug' so debug() logs will be output.--quiet, --silent
: Set the logging level to 'warn' so only warn() and error() logs will be output.
Coercion and casting using validators
You can apply coercion and casting using various validators:
Flag validator
INT
(orINTEGER
): Check option looks like an int and cast it withparseInt()
FLOAT
: Will Check option looks like a float and cast it withparseFloat()
BOOL
(orBOOLEAN
): Check for string like0
,1
,true
,false
,on
,off
and cast itLIST
(orARRAY
): Transform input to array by splitting it on commaREPEATABLE
: Make the option repeatable, eg./mycli -f foo -f bar -f joe
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { // options.kind = 'margherita' // options.number = 1 // options.addIngredients = ['pepperoni', 'onion'] // options.discount = 1.25 }; prog; // ./myprog order pizza --kind margherita --discount=1.25 --add-ingredients=pepperoni,onion
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' // concat files action { }; prog; // Usage:// ./myprog concat -f file1.txt -f file2.txt -f file3.txt
Function validator
Using this method, you can check and cast user input. Make the check fail by throwing an Error
,
and cast input by returning a new value from your function.
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { // options = { "kind" : "MARGHERITA" } }; prog; // ./myprog order pizza --kind margherita
Array validator
Using an Array
, Caporal will check that it contains the argument/option passed.
Note: It is not possible to cast user input with this method, only checking it, so it's basically only interesting for strings, but a major advantage is that this method will allow autocompletion of arguments and option values.
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { }; prog; // ./myprog order pizza --kind margherita
RegExp validator
Simply pass a RegExp object to test against it. Note: It is not possible to cast user input with this method, only checking it, so it's basically only interesting for strings.
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' action { }; prog; // ./myprog order pizza --kind margherita
Colors
By default, Caporal will output colors for help and errors.
This behaviour can be disabled by passing --no-color
.
Auto-generated help
Caporal automatically generates help/usage instructions for you.
Help can be displayed using -h
or --help
options, or with the default help
command.
Custom help
You can add some custom help to the whole program or to specific commands using .help(text, options?)
. The text, even if multi-line, will be, optionally, automatically indented.
Multiple help sections, with custom names, are supported.
Custom help for the whole program
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' // here our custom help for the whole program action { }; prog;
Custom help for specific commands
#!/usr/bin/env nodeconst prog = ;prog version'1.0.0' // first command // here our custom help for the `order` command action { } // second command // here our custom help for the `cancel` command action { } prog;
Typo suggestions
Caporal will automatically make suggestions for option typos.
Shell auto-completion
Caporal comes with an auto-completion feature out of the box for bash
, zsh
, and fish
,
thanks to tabtab.
For this feature to work, you will have to:
- Put your cli app in your
$PATH
(this is the case if your app is installed globally usingnpm install -g <myapp>
) - Setup auto-completion for your shell, like bellow.
If you are using bash
# For bash source <(myapp completion bash) # or add it to your .bashrc to make it persist echo "source <(myapp completion bash)" >> ~/.bashrc \&& source ~/.bashrc
If you are using zsh
# For zsh source <(myapp completion zsh) # or add it to your .zshrc to make it persist echo "source <(myapp completion zsh)" >> ~/.zshrc \&& source ~/.zshrc
If you are using fish
# For fish source <(myapp completion fish) # or add it to your config.fish to make it persist echo "source <(myapp completion fish)" >> ~/.config/fish/config.fish \&& source ~/.config/fish/config.fish
Basic auto-completion
By default, it will autocomplete commands and option names. Also, options having an Array validator will be autocompleted.
Auto-completion setup example
#!/usr/bin/env node const prog = ; prog version'1.0.0' // the "order" command // <kind> will be auto-magicaly autocompleted by providing the user with 3 choices // enable auto-completion for <from-store> argument using a sync function returning an array complete { return 'store-1' 'store-2' 'store-3' 'store-4' 'store-5'; } // enable auto-completion for <account> argument using a Promise complete { return Promise; } // enable auto-completion for -p | --pay-by option using a Promise complete { return Promise; } // -e | --extra will be auto-magicaly autocompleted by providing the user with 3 choices action { logger; logger; logger; } // the "return" command // enable auto-completion for <order-id> argument using a Promise complete { return Promise; } // enable auto-completion for --ask-change option using a Promise complete { return Promise; } action { logger; logger; logger; }; prog;
API
require('caporal')
Returns a Program
instance.
Program API
.version(version) : Program
Set the version of your program. You may want to use your package.json
version to fill it:
const myProgVersion = version;const prog = ;prog versionmyProgVersion// [...] prog;
Your program will then automaticaly handle -V
and --version
options:
matt@mb:~$ ./my-program --version
1.0.0
.help(text, options?) : Program
Add a program-level help section.
By default the optional options
parameter is:
indent: true // If `true` the text will be automatically indented name: "MORE INFO" // The name of the section
.command(name, description) -> Command
Set up a new command with name and description. Multiple commands can be added to one program. Returns a {Command}.
const prog = ;prog version'1.0.0' // one command action { logger} // you must attach an action for your command // a second command action { logger} // a command may have multiple words action { logger}// [...] prog;
.logger([logger]) -> Program | winston
Get or set the logger instance. Without argument, it returns the logger instance (winston by default). With the logger argument, it sets a new logger.
Command API
.argument(synopsis, description, [validator, [defaultValue]]) -> Command
Add an argument to the command. Can be called multiple times to add several arguments.
- synopsis (String): something like
<my-required-arg>
or[my-optional-arg]
- description (String): argument description
- validator (Caporal Flag | Function | Array | RegExp): optional validator, see Coercion and casting
- defaultValue (*): optional default value
.option(synopsis, description, [validator, [defaultValue, [required]]) -> Command
Add an option to the command. Can be called multiple times to add several options.
- synopsis (String): You can pass short or long notation here, or both. See examples.
- description (String): option description
- validator (Caporal Flag | Function | Array | RegExp): optional validator, see Coercion and casting
- defaultValue (*): optional default value
- required (Bool): Is the option itself required ? Default to
false
.help(text, options?) -> Command
Add a command-level help section.
By default the optional options
parameter is:
indent: true // If `true` the text will be automatically indented name: "" // The name of the section, by default this line won't be displayed
.action(action) -> Command
Define the action, e.g a Function, for the current command.
The action callback will be called with 3 arguments:
- args (Object): Passed arguments
- options (Object): Passed options
- logger (winston): Winston logger instance
// sync actionconst prog = ;prog version'1.0.0' action { logger };
You can make your actions async by using Promises:
// async actionconst prog = ;prog version'1.0.0' action { return /* ... */; };
.alias(alias) -> Command
Define an alias for the current command. A command can only have one alias.
const prog = ;prog version'1.0.0' // one command action { logger}; prog; // ./myapp w// same as// ./myapp walk
.complete(completer) -> Command
Define an auto-completion handler for the latest argument or option added to the command.
- completer (Function): The completer function has to return either an
Array
or aPromise
which resolves to anArray
.
.visible(visibility?) -> Boolean | Command
Get or set the visibility value of this command. By default it's true
, if you set it to false
it will be omitted from the help message.
const prog = ;prog version'1.0.0' // one command prog;
Credits
Caporal is strongly inspired by commander.js and Symfony Console. Caporal makes use of the following npm packages:
- colorette for colors
- cli-table3 for cli tables
- fast-levenshtein for suggestions
- tabtab for auto-completion
- minimist for argument parsing
- prettyjson to output json
- winston for logging
License
Copyright © Matthias ETIENNE
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The Software is provided “as is”, without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the Software.