shon v4.0.0
shon
Shon is a JavaScript command-line argument parser. Fully describe your command's interface using familiar usage notation. Since the declarations are complete, Shon can provide informative errors for all missing or invalid configuration values. Shon supports both optional and required flags and arguments, as well as subcommands.
Shon also supports a recursive descent parser for Shell Object Notation (SHON), so complex objects can be expressed as command line arguments.
Install shon with npm, for both the usage to JSON translator and the lightweight argument parser.
$ npm install --save shonThe following is a .usage file.
offer
name: <name> A required argument that populates the
`name` config property.
age: <age> :number A required argument that populates the
`age` config property with a number.
resume: <filename> :input A required file name or "-" for standard
input that populates the `resume` config
property with a readable stream.
offer: [<filename>] :output An optional file name or "-" for standard
output that populates the `offer` config
property with a writable stream.
Defaults to standard output.
nick: [<nickname>] An optional argument that populates the
`nick` config property.
active: [-a] A boolean flag, defaults the active config
variable to false, true if -a is present
among arguments.
enabled: [-e|--enabled] A boolean flag, accepted as either a long
or short flag.
salary: [-s|--salary <salary>] :number An optional flag with an argument,
defaults the `salary` config variable to
null, or a number if defined.
The salary argument must be a valid number.
prefers: [-S=salary*|-E=equity] An optional flag that sets the `prefers`
config property to either "salary" or
"equity", and defualts to "salary".
available: -a=true|-A=false :boolean A required flag, either little or big A,
parsed as boolean.
description: [-d <description>] :atinput An optional description, either as text
in the argument, or in a file if the
filename is prefixed with @ like
@desc.txt
prize: [-p <place>] :quantity An optional prize place, a number that
must be 1 or more.
misc: [-m <misc>] :json Unstructured data expressed as JSON
on the command line. Must parse properly.
config: [-c <config>] :shon A configuration expression in JSON or SHON,
which looks like [ --key value ] and can
express nested objects and arrays.The usage2shon utility converts usage files
to a JSON description of the command.
You can set up building usage in your pakcage.json then just run npm run
usage to build a new usage JSON.
{
"scripts": {
"usage": "usage2shon offer.usage > offer.json
}
}The shon/exec module accepts the JSON description and produces a
configuration object, or reports errors to the console and returns null.
'use strict';
var shon = require('shon/exec');
var usage = requir('./offer.json');
function main() {
var config = shon(usage);
if (config == null) {
return;
}
console.log('active:', config.active);
console.log('enabled:', config.enabled);
}Subcommands
...
Usage Grammar
The grammar for parsing usage has the following semantics:
Each term may have some combination of flags and an argument. Flags and arguments combine in various ways:
[-f|--flag]An optional flag. Each flag may specify a value, like-a=alpha|-b=beta. If none of the flags specify a value, the variable will be a boolean, false by default, and switched to true by the presence of any of the flags.[-f|--flag] <argument>A required argument, optionally specified with a flag. So, if a command accepts multiple arguments, they will be taken from the command line in order, but can be specified in any order using flags.[-f|--flag <argument>]An optional flag with an argument. The argument can only be specified with the flag.-f|--flag <argument>A required flag with an argument. The argument can only be specified with the flag.<argument>A required argument. The argument must appear in the declared order on the command line.
Future versions of this library intend to add support for other idioms,
including the -v/-q idiom for upgrading or downgrading verbosity.
By default, an argument will set a single configuration value. However, with a collector annotation, each argument may append a value onto an array.
<argument>...An argument that may be specified any number of times. The configuration value will be an array, empty by default.<argument>{count}The argument must be specified exactlycounttimes.<argument>{min..}The argument must be specified at leastmintimes.<argument>{min..max}The argument must be specified at leastmintimes and no more thanmaxtimes.
Each term may be followed by a type annotation.
:booleanmeans that the argument must either be the stringtrueor the stringfalse, with the corresponding boolean values.:numbermeans that the argument must represent a number, not NaN.:quantitymeans that the argument must represent a positive integer.:shonmeans that the value of the argument must be expressed with SHON (shell object notation), described hereafter.:jshonmeans that the value of the argument must be expressed with JSON or SHON with JSON possibly embedded in place of values.:jsonmeans that the value of the argument must be expressed with JSON.:inputproduces a readable stream from a file name, or-for standard input. Standard input is implied if the argument is optional and the argument is omitted.:atinputproduces a readable stream, from the literal argument, or from a file name if prefixed with@, or standard input if@-.:outputproduces a writable stream from a file name, or-for standard output. Standard output is implied if the argument is optional and omitted.
Future versions of this library will introduce further type annotations for
reading and writing by file name or -.
Usage Model
The command usage model is designed with the intent that other libraries will provide a higher level interface that produce it (like a tool that automatically abbreviates and creates negative flags), and other utilities that will consume it (like a tool that provides shell completion).
The Command constructor generates a command model object, suitable for
passing to exec, parse, or usage functions, or a variety of other
possible uses.
These functions require an object with the following shape:
_namethe name of the command._termsis an array of terms. Each term corresponds to a configuration variable and describes all of the argument forms necessary to populate it.
The Command constructor also reveals each term by its name to make it easier
to programmatically manipulate each term after the skeleton has been generated.
Each term has the following shape:
namethe name of the corresponding configuration variable.flagsan array of flags.argthe name of the term's argument ornullif it does not accept one.commandsan object mapping subcommand names to command shapes, ornullif not applicable.collectorTypeisarrayfor arrays of any size ornullif the term collects a single value. A future version may introduce adifferencecollector for upgrading or downgrading a value.typeis an arbitrary type name which may have custom parsers, converters, validators, or collectors associated. SHON provides behaviors forboolean,number,quantity,json,shon, andjshon.parseris an optional parser constructor.converteris an optional converter object or function.validatoris an optional validator object or function.collectoris an optional collector object or function.requiredimplies that this term must be specified on the command line.optionalFlagimplies that this term's argument can be specified either in order or earlier if specified with its flag.minLengthif the term is an array, the minimum length, albeit 0maxLengthif the term is an array, the maximum length, albeit Infinity
A flag has the following shape:
flagis the full text of the flag including the-or--prefix.longistrueif the prefix is--shortistrueif the prefix is-valueis the string representation of the value that this flag will set. It will be converted and validated based on the term's type.defaultistrueif the flag produces the default value.
Converters
Converter objects implement a convert method. Converter functions accept a
string from the command line and return the corresponding JavaScript value.
They also receive an iterator and delegate object which can be used
to report errors and halt the parser.
function convertBoolean(string, iterator, delegate) {
if (string === 'true') {
return true;
} else if (string === 'false') {
return false;
} else {
delegate.error('Must be true or false');
delegate.cursor();
}
}Validators
Validator objects implement a validate method. Validate functions accept a
value and return whether it is valid.
...
Collectors
...
Parsers
...
Iterators
...
Cursors
...
Delegates
...
SHON (SHell Object Notation)
SHON is an idiomatic notation for expressing objects at the command line.
All of JSON can be expressed with SHON.
SHON lends itself better to command line usage for the purposes of
interpolating variables and tab completion.
Any parser can accept SHON with the :shon type annotation.
| Type | JSON | SHON |
|---|---|---|
| Object | {"hello": "World"} | [ --hello World ] |
| Array | ["beep", "boop"] | [ beep boop ] |
| Array | [1, 2, 3] | [ 1 2 3 ] |
| Empty Array | [] | [ ] or [] |
| Object | {"a": 10, b: 20} | [ --a 10 --b 20 ] |
| Empty Object | {} | [--] |
| Number | 1 | 1 |
| Number | -1 | -1 |
| Number | 1e3 | 1e3 |
| String | "hello" | hello |
| String | "hello world" | 'hello world' |
| String | "10" | -- 10 |
| String | "-10" | -- -10 |
| String | "-" | -- - |
| String | "--" | -- -- |
| True | true | -t |
| False | false | -f |
| Null | null | -n |
SHON subexpressions can be interpolated with a bare $SHON variable.
The proper idiom for interpolating an arbitrary string in SHON is --
"$VARIABLE".
This ensures that the variable is interpreted as a string literal in place.
This package ships with a shon command for converting SHON to JSON at the
command line.
Acknowledgements
This project is based on earlier work implemented for NarwhalJS by Kris Kowal, Tom Robinson, and Abhinav Gupta. Abhinav is responsible for having contrived the brilliant name, SHON.
Copyright (c) 2009-2015 Contributors MIT License