Package Exports
- argp
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (argp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
argp
Node.js project
Command-line option parser
Version: 0.0.13
Inspired by the extremly well-known argp C library, this module parses GNU-style command-line options. Help, usage and version messages are automatically generated and line-wrapped at 80 columns. The module checks for errors, can be easily adapted to your needs thanks to its evented system and it also works when Node.js is in debug mode. The module is uncached and each property is deleted once all the input parameters have been parsed, so there's no memory footprint.
This module it's made for you if you want:
- Robust solution that reads GNU-style options.
- Command configuration.
- Basic error checking.
- Nice help messages without caring about indentation, multilines, etc.
- Zero memory footprint.
A common configuration looks like this:
//If you can, don't cache the module
var argv = require ("argp")
.description ("Sample app.")
.email ("a@b.c")
.body ()
//The object an argument definitions and the text of the --help message are
//configured at the same time
.text (" Arguments:")
.argument ("arg", { description: "Sample argument" })
.text ("\n Options:")
.option ({ short: "o", long: "opt", description: "Sample option" })
.help ()
.version ("v1.2.3")
.end ()
.argv ();
console.log (argv);
/*
$ node script.js
{
opt: false,
help: false,
version: false,
arg: false
}
$ node script.js --help
Usage: t.js [options] [arguments]
Sample app.
Arguments:
arg Sample argument
Options:
-o, --opt Sample option
-h, --help Display this help message and exit
-v, --version Output version information and exit
Report bugs to <a@b.c>.
*/If you have a package.json file you can take from it the description, email and version using the readPackage() function. Take into account that this function calls a synchronous fs operation. Doesn't really matter because this module is the first thing you're going to execute.
var argv = require ("argp")
//If no path is provided, it tries to read the "./package.json" file
.readPackage ("path/to/package.json")
.body ()
.text (" Arguments:")
.argument ("arg", { description: "Sample argument" })
.text ("\n Options:")
.option ({ short: "o", long: "opt", description: "Sample option" })
.help ()
.end ()
.argv ();Installation
npm install argpDocumentation
- Quick examples with no configuration
- Configuring options
- Configuring arguments
- Configuring commands
- Full example explained
Objects
Quick examples with no configuration
If an option has not been defined the type of the value is converted automatically from a string to a number, boolean, null or undefined.
By default the parser doesn't allow undefined arguments and options because you typically want to have an absolute control over the calls to your program in order to avoid unexpected behaviours. Allowing undefined arguments and options is as simple as this:
var argv = require ("argp")
.allowUndefinedArguments ()
.allowUndefinedOptions ()
.argv ();$ node script.js -a -b -c
{ a: true, b: true, c: true }
$ node script.js a b c
{ a: true, b: true, c: true }
$ node script.js -abc null
{ a: true, b: true, c: null }
$ node script.js --a --b 1 --d=e
{ a: true, b: 1, d: "e" }
$ node script.js --no-a b
{ a: false, b: true }
$ node script.js --a -- -b --c d
{ a: true, "-b": true, "--c": true, d: true }Considerations:
By default the options are flags. If the option requires a value, the
argumentproperty must be defined. This property is a string and can be seen when the --help message is printed. For example,$ node script.js --help ... o, --opt=STR Sample option ...
Where STR is the argument property.
By default, the value of the options is a string. Configure the
typeproperty if the value is a number, boolean (rarely used, use a flag instead) or array (comma-separated values).Each option has an id which is used to store the value into the final object. This id is the long name. If the long name has not been defined then the id is the short name.
.option ({ short: "a", long: "aa" }) //{ aa: false } .option ({ long: "aa" }) //{ aa: false } .option ({ short: "a" }) //{ a: false }
Common properties between flags and options with value:
- description - String
The description. - hidden - Boolean
If true, the option is not displayed in the --help and --usage messages. Default is false. - long - String
The long name. Cannot contain white spaces. - short - String
The short name. It must be an alphanumeric character.
Flags:
negate - Boolean
If true, the flag is negated..option ({ short: "o", long: "opt", negate: true })
$ node script.js { opt: true } $ node script.js --opt { opt: true } $ node script.js --no-opt { opt: false } $ node script.js -o { opt: false }
Options with value:
aliases - Array
An alias it's a long-name option that points to another option..body () .option ({ long: "name", aliases: ["foo", "bar"] }) .help () .usage ()
$ node script.js --usage Usage: script [--name|--foo|--bar] [-h|--help] [--usage] $ node script.js --help Usage: script [options] --name, --foo, --bar -h, --help Display this help message and exit --usage Display a short usage message and exit
The
options()function returns an object with all the configured options:{ name: { ... }, foo: { ... }, bar: { ... }, help: { ... }, usage: { ... } }
Where
name,fooandbarpoint to the same object:.on ("start", function (){ var options = this.options (); assert.ok (options.name === options.foo && options.name === options.bar); })
argument - String
Must be configured if the option requires a value. The string is used when the --help message is printed..option ({ long: "name", argument: "STR" })
$ node script.js --help ... --name=STR ...
choices - Array
The input value must be one of the choices. If the option defines theoptionalproperty thechoicesproperty is ignored..option ({ long: "opt", argument: "NUM", type: Number, choices: [1,2,3] })
$ node script.js --opt=1 { opt: 1 } $ node script.js --opt=7 # Error!
When
defaultandchoicesare configured in the same option the default value doesn't need to match a choice:.option ({ long: "opt", argument: "STR", default: "d", choices: ["a", "b", "c"] })
$ node script.js { opt: "d" }
default - Object
The default value..option ({ long: "name", argument: "STR", default: "bar", optional: true })
$ node script.js { name: "bar" } $ node script.js --name { name: "bar" } $ node script.js --name foo { name: "foo" }
optional - Boolean
If true, the value is optional. Default is false. If the option doesn't receive any value the default value is set and it depends on thedefaultandtypeproperties..option ({ long: "name1", argument: "STR", optional: true }) .option ({ long: "name2", argument: "NUM", optional: true, type: Number }) .option ({ long: "name3", argument: "ARR", optional: true, type: Array }) //Boolean type is rarely used, use a flag instead .option ({ long: "name4", argument: "BOOL", optional: true, type: Boolean })
$ node script.js --name1 --name2 --name3 # "name1" is null because all the options are strings by default, and the default value of a string is null # "name2" is 0 because the default value of a number is 0 # "name3" is [] because the default value of an array is [] # "name4" is false because the default value of a boolean is false { name1: null, name2: 0, name3: [], name4: false }
$ node script.js --name1 foo --name2 12 --name3 -12.34,foo,true --name4 true { name1: "foo", name2: 12, name3: [-12.34, "foo", true], name4: true }
reviver - Function
The function is executed when the option is parsed. It is similar to the reviver of theJSON.parse()function. This is the right place where you can validate the input data andfail()if is not valid. For example, if the option requires a number you can validate the range here..option ({ long: "name", argument: "STR", reviver: function (value){ return value + "bar"; }})
$ node script.js --name foo { name: "foobar" }
.option ({ long: "opt", argument: "NUM", type: Number, reviver: function (value){ //"value" is already a number if (value < 1 || value > 3){ require ("argp").fail ("Option 'opt': invalid range"); } return value; }})
type - String | Number | Boolean | Array
The type of the value. Default is a String. If the type is an Array, comma-separated values are automatically stored into an array and each element is converted to the type it represents..option ({ long: "name", argument: "ARR", type: Array })
$ node script.js --name 1,true,foo { name: [1, true, "foo"] }
Example: options.js.
Properties:
- description - String
The description. - hidden - Boolean
If true, the option is not displayed in the --help and --usage messages. Default is false.
Note: help and trailing properties can be also configured but they are related with the commands.
.argument ("arg1")
.argument ("arg2", { description: "foo" })
.argument ("arg3", { description: "bar", hidden: true })$ node script.js arg1
{ arg1: true, arg2: false, arg3: false }
$ node script.js --help
...
arg1 foo
arg2 bar
...Example: options.js.
A command is an argument followed by other arguments and options. NPM is an example:
npm config set <key> [<value>]
npm install [<package>...] -gconfig is a command and set an argument with 2 trailing arguments: minimum 1, maximum 2.install is a command with infinite trailing arguments: minimum 0, maximum Infinity. -g is an option which only applies to the install command.
var argv = require ("argp")
.main ()
.description ("Main menu")
.body ()
.help ()
.usage ()
.end ()
.command ("config")
.body ()
.argument ("set", { help: "set <key> [<value>]",
trailing: { min: 1, max: 2 } })
.help ()
.end ()
.command ("install", { trailing: {} })
.body ()
.option ({ short: "g", long: "global" })
.usage ()
.end ()
.argv ()
console.log (argv);
/*
$ node script.js -h
Usage: script [options]
Main menu.
-h, --help Display this help message and exit
--usage Display a short usage message and exit
$ node script.js config -h
Usage: t config [options] [arguments]
set <key> [<value>]
-h, --help Display this help message and exit
$ node script.js config set 1 2
{ config: [], set: [ 1, 2 ] }
$ node script.js install --usage
Usage: t install [-g|--global] [--usage]
$ node script.js install 1 2 3 -g
{ install: [ 1, 2, 3 ], global: true }
*/If you have a very few commands you can configure them like above, chaining the commands, but you typically want to modularize them, one command per file. Then you should check the npm.js example.
The commands are configured exactly the same way as the Argp instance with only one difference: argument() accepts 2 new properties:
help - String
The string replaces the argument name in the help message..argument ("set", { description: "Sample argument" }); /* ... set Sample argument ... */ .argument ("set", { help: "set <key> [<value>]", description: "Sample argument" }); /* ... set <key> [<value>] Sample argument ... */
trailing - Object
Configures how many arguments must follow this argument.There are 3 properties:
eq,minandmax.eqcannot be used withminormax. Ifminandmaxare being used, by defaultminis 0 andmaxis Infinity. Atrailingobject without any of these 3 properties defaults tomin0,maxInfinity.Some examples:
2 arguments required:
foo x <y> <y>..argument ("x", { trailing: { eq: 2 } })
1 required, 1 optional:
foo x <y> [<y>]..argument ("x", { trailing: { min 1, max: 2 } })
1 optional:
foo x [<y>]..argument ("x", { trailing: { max: 1 } })
1 required, infinite optional:
foo x <y> [<y>...]..argument ("x", { trailing: { min: 1 } })
Infinite:
foo x [<y>...]..argument ("x", { trailing: {} })
No arguments:
foo x..argument ("x")
Multiple commands in the same line. command
xwith 1 required, and commandywith infinite arguments:foo x <y> z [<w>...]..argument ("x", { trailing: { eq: 1 } }) .argument ("z", { trailing: {} })
/*
Avoid storing the module in a variable because when the parser finishes it
is removed from the cache. If you store a reference remember to unreference it
if you want a zero memory footprint.
var argp = require ("argp")
var argv = ...
argp = null;
*/
var argv = require ("./lib")
//The evented system allows you to fully adapt the module to your needs
//The "start" and "end" events are useful when you need to initialize or
//clean up things
.on ("start", function (argv){
//Emitted after the default values of the configured options and arguments
//have been set and before starting the read.
//"argv" is the final object
})
.on ("argument", function (argv, argument, ignore){
//Emitted when an argument is found
//"argv" is the final object
//"argument" is the argument found
//"ignore" is a function that when called ignores the argument, hence it
//it isn't stored in the final object
})
.on ("option", function (argv, option, value, long, ignore){
//Emitted when an option is found
//"argv" is the final object
//"option" is the name of the option found
//"value" is the value of the option after calling the reviver, if any
//"long" is a boolean; true if the option is a long name, otherwise false
//"ignore" is a function that when called ignores the argument, hence it
//it isn't stored in the final object
})
.on ("end", function (argv){
//Emitted when all the options and arguments have been read
//"argv" is the final object
})
//Wrap lines at 100 columns, default is 80
.columns (100)
//If "sort" is enabled, the options are parsed before the arguments, if not,
//the options and arguments are parsed in the same order they come
.sort ()
//Allow undefined arguments
.allowUndefinedArguments ()
//Allow undefined options
.allowUndefinedOptions ()
//The [arguments] part of the "usage" line in the --help and --usage messages can be changed
//See "custom-usages.js" example
.usages ([
"foo",
"bar"
])
//Print a description at the top of the help message
.description ("Sample app.")
//Print a contact email at the end of the help message
.email ("a@b.c")
//Configure the body
.body ()
//The object an argument definitions and the text of the --help message are
//configured at the same time
//The order of the configuration is important
//Print a text
.text ("Random text")
//Print a line with 2 columns
.columns ("col1", "col2")
//Define arguments and options
.argument ("arg1", { description: "aaa" })
.argument ("arg2")
.option ({ short: "a", long: "aa", description: "aaa" })
.option ({ short: "b", long: "bb", type: Number, description: "bbb" })
//Enable the -h, --help option
.help ()
//Enable the --usage option
.usage ()
//Enable the -v, --version option
.version ("v1.2.3")
//Explicit ending
.end ()
//Parse the options
.argv ();The module returns an instance of Argp. It inherits from an EventEmitter.
The parser follows the GNU-style rules: -a, -abc, --a, --no-a, --a=b, etc. Long option abbreviation is also supported.
If you don't want to configure anything simply require the module, allow undefined arguments and options and call to argv().
var argv = require ("argp")
.allowUndefinedArguments ()
.allowUndefinedOptions ()
.argv ();Note: If no configuration is provided you cannot join a short name with its value in the same token, eg: -Dvalue, all the characters following a dash, -, are interpreted as individual flags.
Events
With the event system you can fully adapt this module to yours needs. Example: (to-upper-case.js).
Methods
- Argp#allowUndefinedArguments() : Argp
- Argp#allowUndefinedOptions() : Argp
- Argp#arguments() : Object
- Argp#argv() : Object
- Argp#body() : Body
- Argp#columns(columns) : Argp
- Argp#command(name[, configuration]) : Command
- Argp#commands() : Argp
- Argp#description(str) : Argp
- Argp#email(str) : Argp
- Argp#fail(str[, code]) : undefined
- Argp#main() : Argp
- Argp#options([filter]) : Object
- Argp#readPackage([path]) : Argp
- Argp#sort() : Argp
- Argp#usages(usages) : Argp
Objects
Emitted when an argument is found.
Parameters:
- argv - Object
The final object. - argument - String
The name of the argument found. - ignore - Function
When the function is called the parser ignores the argument, hence it isn't stored in the final object.
Emitted when all the options and arguments have been parsed. The following 3 functions can be cached, they are safe to use at any time, they won't introduce a memory leak.
Parameters:
- argv - Object
The final object. - printHelp - Function
Prints the help message and exits with code 0. - printUsage - Function
Prints the usage and exits with code 0. - printVersion - Function
Prints the version, if it was configured, and exits with code 0.
Emitted when an option is found.
Parameters:
- argv - Object
The final object. - option - String
The name of the option found. - value - String
The value of the option after calling the reviver, if any. - long - Boolean
True if the option is a long name, otherwise false. - ignore - Function
When the function is called the parser ignores the argument, hence it isn't stored in the final object.
Emitted just before the parser begins to read the input data.
Parameters:
- argv - Object
The final object. The default values are already set.
Argp#allowUndefinedArguments() : Argp
Allows undefined arguments.
Argp#allowUndefinedOptions() : Argp
Allows undefined options.
Returns the configured arguments. Look at the internal-data.js example for further details.
Parses the process.argv array. It uncaches and nulls the module after parsing the input data.
Returns a Body instance.
Sets a maximum line length. By default lines are wrapped at 80 columns.
Argp#command(name[, configuration]) : Command
Configures a command. A command it's like a new fresh cli program. It behaves exactly like an Argp. See Configuring commands.
Returns the configured commands.
Look at the internal-data.js example for further details.
Sets a description. The description is printed at the start of the --help message, after the usage lines.
Sets a contact email. The email is printed at the end of the --help message.
Argp#fail(str[, code]) : undefined
Prints a message to the stderr and exists the program. By default it exists with code 1.
Returns de Argp instance. It's a no-op function, just for a better visual organization when configuring commands.
Look at the npm.js example for further details.
Argp#options([filter]) : Object
Returns the configured options. filter is an object which can be used to return the options with a short name or with a long name.
.options ()
.options ({ short: true })
.options ({ long: true })Look at the internal-data.js example for further details.
Argp#readPackage([path]) : Argp
Reads a package.json file and configures the parser with the description, email and version. If no path is provided it uses the ./package.json path. It's an fs synchronous operation.
Changes the "usage" line from the --help and --usage messages. usages is an array of strings.
Look at the custom-usages.js example for further details.
If sort() is enabled, the options are parsed before the arguments, if not, the options and arguments are parsed in the same order they come.
The Body instance is returned by Argp#body(). All the following functions print a message in the same order they are configured, this allows you to fully customize the --help message very easily.
Look at fully-descriptive-help.js for further details.
Methods
- Body#argument(name[, configuration]) : Body
- Body#columns(column1, column2) : Body
- Body#end() : Argp
- Body#help() : Body
- Body#option(o) : Body
- Body#text(str[, prefix]) : Body
- Body#usage() : Body
- Body#version(str) : Body
Body#argument(name[, configuration]) : Body
Defines an argument. See Configuring arguments.
Body#columns(column1, column2) : Body
Prints a line with 2 columns. The first columns shouldn't contain line breaks (\n). This functionality is used to print the options and arguments.
Returns the Argp instance. Use it to explicitly end the body configuration.
Enables the -h, --help option.
Defines an option. See Configuring options.
Body#text(str[, prefix]) : Body
Prints a text message. Line-wrapped at 80 columns by default and supports multilines (line breaks, \n). The prefix is mainly used to indent the text with a some spaces.
Enables the --usage option.
Enables the -v, --version option. str is the text to print when the option is called.