@davebenson/option-parser
v2.0.1
Published
A not-too-simple command-line option parser
Maintainers
Readme
daveb-option-parser
An option parser that does useful type checking as well as generating a usage message.
Motivation: Why Another Option Parser?
- better error-handling. All too often argument parsers do too little type-checking and force the work to be ad hoc throughout the code.
- better usage message
- no dependencies
Example
import {OptionParser} from '@davebenson/option-parser';
// configure options for a very simple counting program.
const optionParser = new OptionParser({
description: 'Print a finite number of evenly spaced numbers.'
});
optionParser.addInt('count', 'number of lines to print').setMandatory();
optionParser.addFloat('step', 'difference between numbers').setDefaultValue(1);
optionParser.addString('prefix', 'print this before each line').setDefaultValue('');
const options = optionParser.parse(); // terminates if there are problems
// main program
for (let i = 0; i < options.count; i++)
console.log(options.prefix + (options.step * i));Example: constraints
const optionParser = new OptionParser({
description: 'Flip a weighted coin'
});
optionParser.addFloat('prob', 'probability of heads')
.setDefaultValue(0.5)
.setMinimum(0.0)
.setMaximum(1.0);
.addShortCode('p');
const options = optionParser.parse();
console.log(Math.random() < options.prob ? 'HEAD' : 'TAILS');Example: Creating a new type.
import {OptionParser, TypeInfo} from 'daveb-option-parser';
const optionParser = new OptionParser({
description: 'Add two 3-d vectors'
});
class TypeInfoVector3 extends TypeInfo {
constructor() {
super('vector3');
}
parse(value) {
const pieces = value.split(',');
if (pieces.length !== 3)
throw new Error('expected x,y,z');
return pieces.map(parseFloat);
}
});
optionParser.registerType(new TypeInfoVector3());
optionParser.addGeneric('a', 'vector3', 'addend 1').setMandatory();
optionParser.addGeneric('b', 'vector3', 'addend 2').setMandatory();
const options = optionParser.parse(); // terminates if there are problems
// main program
const a = options.a, b = options.b;
const sum = [a[0] + b[0], a[1] + b[1], a[2] + b[2]];
console.log(sum.join(','));Example: Command with Different Modes
import {OptionParser} from 'daveb-option-parser';
const optionParser = new OptionParser({
description: 'read/write a string to a file'
});
optionParser.addString('file', 'file to read/write');
optionParser.addMode(
'write',
{
shortDescription: 'write the file'
},
(op) => {
op.addString('contents', 'file contents');
}
);
optionParser.addMode(
'read',
{
shortDescription: 'read the file'
}
);
const options = optionParser.parse();
switch (options.mode) {
case 'read': {
fs.readFile(options.file, {encoding:'utf8'}, (err, str) => {
if (err) {
throw err;
} else {
console.log(str);
}
});
break;
}
case 'write': {
fs.writeFile(options.file,
options.write.contents,
{encoding:'utf8'},
(err) => { if (err) throw err; }
break;
}
}Reference Documentation
OptionParser class
new OptionParser([options])
Create a new OptionParser. Options is an object which may contain the following fields:
camelCase: store values keyed by camelCase rather than lowercase_underscore_separatedpermitArguments: make the option-parser argumentative. j/k. Actually, this makes it so that we collect non-option command-line arguments into the parser'sargumentsmember. It can take one of a number of types. Set permitArgments() below for possible values.errorHandler: function to call if something goes wrong. If unspecified, the program will terminate with an error message.name: application name, used in usage summary.description: human-readable blurb that will follow the usage summary in the usage message.
addInt(name, description)
Add an integer parameter to the option-parser.
Returns a new ArgInfo.
addFloat(name, description)
Add an float parameter to the option-parser.
Returns a new ArgInfo.
addString(name, description)
Add a string parameter to the option-parser.
Returns a new ArgInfo.
registerType(typeInfo)
Add a new type to the option-parser.
addGeneric(name, type, description)
Add a new parameter to the option-parser.
addArgCallback(name, label, description, fct)
fct() takes arguments (argument, values, argInfo, typeInfo, optionParser). It should throw an error to report problems. Whatever is returned by the function will be set in the values object.
addNoArgCallback(name, description, fct)
fct() takes arguments (values, argInfo, typeInfo, optionParser). It should throw an error to report problems.
addShortAlias(shortname, longname)
Alias a one-character name for a long name.
If the original long name takes arguments, they must be given consecutively after the short-option blob in the same order as in the short options.
permitArguments(setting, label)
Configure how unknown arguments are handled.
The setting can be a number of types:
- true: the arguments are taken as strings
- false: arguments are not allowed
- instance of TypeInfo or a string: any number of arguments of this type are allowed
- array of TypeInfo or string: exact type matching is requires
The label is used for constructing the usage message and defaults to uppercase strings based on setting.
setExclusive(required, arrayOfOptionNames)
Prevent more than one of a set of options to be used.
If required, exactly one must be set.
addPreset(name, description, optionDictionary)
When this long-option is encountered, all the various attributes in optionDictionary will be copied into the returned values dictionary.
addMode(name, optionParserOpts, (OptionParser) => undefined)
Add a new submode for this command.
This creates a parser, sets its parent, then involves the configuration callback to set it up.
The optionParserOpts may also contain a modeJavascriptName to use instead of the default value (otherwise computed with the default camelCaseToJavascriptName function).
addModeAlias(newName, oldName)
Create a nickname for an existing mode.
setWrapper(isW)
If true then this program will assume it is a wrapper program
whose arguments after the program name will be directly passed to a subprogram.
They will be captured in the arguments member, along with the executable name.
Calling this function with no arguments is equivalent to calling it with true.
parse([args])
Parse the command-line arguments. If not specified, we process the current process's arguments,
process.argv.
The values are returned as an object, unless an non-fatal non-throwing error-handler was installed and parsing failed, in which case, null is returned.
After running the option parser has a few members set that can be used:
values: this is the same as the return value of the parse.arguments: all non-option arguments are collected here.
getUsage([options])
Return a printable string describing the usage of this program.
If specified, options should be an object with the following optional fields:
width: specify screen width for word-wrapping.
ArgInfo class
Represent metadata about an argument to the program (not the actual value).
This is created by the various add...() functions in the OptionParser class.
Its methods are "chainable" (they return "this"),
so it is common to write create and configuring the argument in one statement, for example:
parser.addInt('some-int', 'an integer').setMandatory().setMinimum(10);setDefaultValue(value)
Populate the returned option values with this value if not given.
setMandatory(m)
Require this option to be given. If 'm' is given, it should be a boolean: whether this is mandatory. If not given, it defaults to true (the argument is mandatory).
setRepeated(r)
Allow this option to be specified multiple times. The entry in the returned 'values' object for this option will be an array of the types. Similarly, setDefaultValue() will typically be given an array (the default default value in this case is the empty array, []). If this option is tagged 'mandatory', then at least one instance must be given.
setTolerateRepeated(r)
The default for argument-less options, normally repeating non-repeated arguments causes an error. If "tolerateRepeated", then instead of an error, just the last value for that argument is reported.
setLabel(labelText)
Set placeholder label for this argument that is displayed
in the usage message. Traditionally this is all uppercase. It
defaults to the type in uppercase. For example in the usage
message we might see --count=INT. INT is the label in that case.
setMinimum(minimumValue)
Value must be greater than or equal to minimumValue.
setStrictMinimum(minimumValue)
Value must be strictly greater than minimumValue.
setMaximum(maximumValue)
Value must be less than or equal to maximumValue.
setStrictMaximum(maximumValue)
Value must be strictly less than maximumValue.
setInterval(minimumValue, strictMaximumValue)
Value must be within halfopen interval: this is equivalent to setMinimum(minimumValue).setStrictMaximum(strictMaximumValue).
addShortCode(code)
One character alias for this argument.
setHidden(isHidden)
A hidden option is not documented in the usage message. It is intended (1) to support deprecated options, (2) to provide a way for a suite of programs to have private interfaces to facilitate working together, (3) providing easter eggs.
It should be seldom-used, and it is a sure sign that someone is trying to do something sneaky!
TypeInfo class
An instance of the TypeInfo class is created when a new type is created via registerType.
You may extend this class to create a new type that can be parsed.
parse(arg, values, argInfo, optionParser)
Usually, you only need the first argument. See example above with vector3.
requiresArg()
Returns whether this type needs an argument. Default: true.
Details of the Usage Message Generation
Unsupported things
tar style arguments
multi-argument options (you must combine them into a single argument for now)
Glossary
Command-Line Arguments: A list of strings given to a command-line program.
In unix, a shell parses and computes these from a shell script or user input.
Traditionally, the first string is a program name.
In node, the first string is 'node' and the second is the script name, and is available as process.argv.
The Argument List follows the program or script name.
Argument List:
Slice of Command-Line Arguments that come after the program or script name.
Long Option:
A double-hyphen-prefixed command-line argument with may have a parameter.
Short Option:
A single-hyphen-prefixed single-character option, an alias to a long option.
Option:
A long option, with possible short option aliases.
Parameter:
A string given to an Option as a command-line argument. Most options take a new parameter, but not all.
Type:
Restrictions on a Parameter. For example, it must be an integer.
Flag:
An option that is a simple boolean that does not require a parameter. If the default is true, then --no-flag can be used to set it false. These options can be repeated, with the last one being the effective value.
Extra Arguments:
Command-line arguments that do not begin with '-' and are
Option Set:
A set of Options and a specification for Extra Arguments.
Mode:
A non-hyphenated command-line argument whose subarguments are governed by a new Option Set.
AUTHOR
Dave Benson
