File | Date | Author | Commit |
---|---|---|---|
test | 2019-04-03 |
![]() |
[13302e] All existing tests now pass. |
.gitignore | 2019-03-15 |
![]() |
[278d14] Ready for Experior |
LICENSE | 2019-03-05 |
![]() |
[6d7afc] Initial commit |
README.md | 2019-04-03 |
![]() |
[2b8f8e] Version 1.0.5 |
build_npm.sh | 2019-03-20 |
![]() |
[93d916] Added npm build script |
minicle.js | 2019-04-03 |
![]() |
[13302e] All existing tests now pass. |
package-lock.json | 2019-04-03 |
![]() |
[010339] New testing framework, application is WIP |
package.json | 2019-04-03 |
![]() |
[2b8f8e] Version 1.0.5 |
Minicle is Node module for easily processing command line switches and arguments.
There are scads of CLI argument processors out there, so why another one? Mostly
because the others aim to do too much and can be a pain to use when you just
need something quick and simple. All it does is parse CLI options. It doesn't
handle exotic edge cases, generate usage information, validate arguments, or
anything else.
NEW in v1.0.5: Minicle now supports GNU-style --
end-of-switches.
var parse = require("minicle");
var optionMap = {
infile: { short: "i", vals: [ ] },
outfile: { short: "s", vals: [ ], max: 1 },
verbose: { short: "v", cnt: 0 },
"@general": { vals: [ ] }
};
parse(optionMap);
The parse
function takes optionMap
as its sole argument, which is an object
containing the command line switches and their parameters. It is altered in
place, so once it returns, you're done!
The keys of the object represent the long form, so infile
becomes --infile
.
The associated value is an object with the switch parameters. The short
member
specifies the short form of the switch, e.g., short: "i"
creates -i
.
Switches with a vals
member containing an array accumulate arguments.
In the case of infile
, the user can specify --infile
or -i
, and any
non-switch tokens following it will be pushed onto the vals
array until the next
switch or the end of the CLI arguments. If the optional max
member is provided,
it specifies a maximum number of arguments, after which further tokens are placed
in the vals
array of the special @general
member. If no @general
member
exists, one will be created.
The following command lines are equivalent:
myprog -i foo -i bar
myprog --infile foo --infile bar
myprog --infile foo bar
// will yield:
var optionMap = {
infile: { short: "i", vals: [ "foo", "bar" ] },
outfile: { short: "s", vals: [ ], max: 1 },
verbose: { short: "v", cnt: 0 },
"@general": { vals: [ ] }
};
But if you try passing multiple arguments to --outfile
, which has max: 1
,
all arguments after the first will end up in @general
:
myprog -o foo -o bar
myprog -o foo bar
// will yield:
var optionMap = {
infile: { short: "i", vals: [ ] },
outfile: { short: "s", vals: [ "foo" ], max: 1 },
verbose: { short: "v", cnt: 0 },
"@general": { vals: [ "bar" ] }
};
Switches with a cnt: 0
member instead of vals
do not take arguments; they
simply accumulate a count of how many times they have been used. The classical
case is a verbosity switch, e.g.:
myprog -v -v -v
myprog --verbose --verbose --verbose
myprog -vvv
// will yield:
var optionMap = {
infile: { short: "i", vals: [ ] },
outfile: { short: "s", vals: [ ], max: 1 },
verbose: { short: "v", cnt: 3 },
"@general": { vals: [ ] }
};
Note that, as usual, short options without arguments can be combined.
Using git-style subcommands requires little more than nesting objects
in optionMap
with the commands as top-level keys. This optionally
includes @none
, which defines switches available when no command is
provided, and @all
, which defines switches available regardless of
the command.
var optionMap = {
add: {
"filename": { short: "f", vals: [ ] },
"overwrite": { short: "o", cnt: 0 },
"@general": { vals: [ ] },
},
update: {
"filename": { short: "f", vals: [ ] },
"force": { short: "F", cnt: 0 },
},
"@none": {
"test": { short: "t", vals: [ ], max: 1 },
"@general": { vals: [ ] },
},
"@all": {
"help": { short: "h", cnt: 0 }
}
};
The following command lines then become possible:
$ myprog add --filename foo.txt -o something
$ myprog remove -f foo.txt -F
$ myprog --test one two three
The first of these yields:
var optionMap = {
add: {
"filename": { short: "f", vals: [ "foo.txt" ] },
"overwrite": { short: "o", cnt: 1 },
"@general": { vals: [ "something" ] },
},
update: {
"filename": { short: "f", vals: [ ] },
"force": { short: "F", cnt: 0 },
},
"@none": {
"test": { short: "t", vals: [ ], max: 1 },
"@general": { vals: [ ] },
},
"@all": {
"help": { short: "h", cnt: 0 }
},
"@subcommand": "add" // this is added by minicle at parse time
};
For minicle to recognize this, the options
argument should include subcommand: true
, e.g.
parse(optionMap, { subcommand: true });
The top-level keys are the subcommands, and their associated objects are the
same as the regular optionMap
when not using subcommands. There are two
additional optional top-level entries, @none
and @all
, both of which are
optional. The @none
object specifies switches that can be used when no
subcommand is given, and @all
specifies switches that can be used with any or
no subcommand.
To avoid a lot of head-scratching confusion, it is important to understand how
the @general
catchall works with subcommands. The @all
options should
not include a @general
entry, and Minicle will remove it for you should
you forget. Each command that accepts general arguments must have its own
@general
, without which general arguments will throw an error. Note that this
includes the @none
subcommand.
If a subcommand is used, minicle will insert it into optionMap
as the value
of a key named @subcommand
.
There are currently two settings that can be passed in the optional options
argument to the parse
function:
subcommands
: If true
, subcommands are enabled.doubleDash
: If true
, the appearance of --
in the command line ends @general
element.Copyright 2019 Erich Waidthaler and subsequent contributors
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.0.5: Added doubleDash
option, improved docs, tested heavily, fixed a bunch of edge cases.
1.0.4: Added @subcommand
to optionMap
results, documented same.
1.0.3: We don't talk about this anymore.
1.0.2: Fixed bug that threw an uncaught exception when no CLI arguments were given.
1.0.1: Updated docs to include the necessary options for subcommands.