Security News
JavaScript Leaders Demand Oracle Release the JavaScript Trademark
In an open letter, JavaScript community leaders urge Oracle to give up the JavaScript trademark, arguing that it has been effectively abandoned through nonuse.
node-cmdln
is a node.js helper lib for creating CLI tools with subcommands
(think git
, svn
, zfs
, brew
, etc.). It is a sister of my earlier
Python lib for this.
Follow @trentmick for updates to node-cmdln.
You define a subclass of Cmdln
and subcommands as do_NAME
methods.
Minimally you could have a "conan.js" as follows:
#!/usr/bin/env node
var util = require('util');
var cmdln = require('cmdln');
function Conan() {
cmdln.Cmdln.call(this, {
name: 'conan',
desc: 'What is best in life?'
});
}
util.inherits(Conan, cmdln.Cmdln);
Conan.prototype.do_crush = function do_crush(subcmd, opts, args, cb) {
console.log('Yargh!');
cb();
};
Conan.prototype.do_crush.help = 'Crush your enemies.';
cmdln.main(new Conan()); // mainline
With this, you get the following behaviour:
$ node examples/conan.js
What is best in life?
Usage:
conan [OPTIONS] COMMAND [ARGS...]
conan help COMMAND
Options:
-h, --help Show this help message and exit.
Commands:
help (?) Help on a specific sub-command.
crush Crush your enemies.
$ node examples/conan.js help crush
Crush your enemies.
$ node examples/conan.js crush
Yargh!
Option processing (using dashdash)
is integrated. do_crush
above could be replaced with:
Conan.prototype.do_crush = function (subcmd, opts, args, cb) {
if (opts.help) {
this.do_help('help', {}, [subcmd], cb);
return;
}
if (!args.length) {
console.log('No enemies? Yarg!');
} else {
args.forEach(function (enemy) {
console.log('Smite %s with a %s!', enemy, opts.weapon);
});
}
cb();
};
Conan.prototype.do_crush.options = [
{
names: ['help', 'h'],
type: 'bool',
help: 'Show this help.'
},
{
names: ['weapon', 'w'],
helpArg: 'WEAPON',
type: 'string',
default: 'sword',
help: 'Weapon with which to smite.'
}
];
Conan.prototype.do_crush.help = (
'Crush your enemies.\n'
+ '\n'
+ 'Usage:\n'
+ ' {{name}} {{cmd}} [OPTIONS] [ENEMIES...]\n'
+ '\n'
+ '{{options}}'
);
Then we get this behaviour:
$ node examples/conan.js crush Bob
Smite Bob with a sword!
$ node examples/conan.js crush Bob Linda --weapon mattock
Smite Bob with a mattock!
Smite Linda with a mattock!
$ node examples/conan.js crush -h
Crush your enemies.
Usage:
conan crush [OPTIONS] [ENEMIES...]
Options:
-h, --help Show this help.
-w WEAPON, --weapon=WEAPON Weapon with which to smite.
See examples/conan.js for the complete example. Run
node example/conan.js ...
to try it out.
One can generate Bash completion code for a Cmdln
subclass via
cli.bashCompletion()
One possible usage is to add a completion
subcmd to your CLI:
CLI.prototype.do_completion = function (subcmd, opts, args, cb) {
console.log( this.bashCompletion() );
cb();
};
and get users to use that to setup Bash completion:
$ alias conan="node examples/conan.js"
$ conan completion > conan.completion
$ source conan.completion
$ conan <TAB>
--help --version -v completion hear see
--verbose -h -x crush help smash
Another potential usage could be to pre-generate a completion file for, and distribute it with, your tool.
In general, please read the comments in the source and browse the examples. The API is far from fully documented here.
cmdln.Cmdln
To use this module you create a class that inherits from cmdln.Cmdln
; add
some methods to that class that define the tool's commands, options, etc.;
then pass an instance to cmdln.main()
. Roughly like this:
function CLI() {
cmdln.Cmdln.call(this, {<config>});
}
util.inherits(CLI, cmdln.Cmdln);
...
var cli = new CLI();
cmdln.main(cli);
We'll use the CLI
and cli
names as used above in the following reference:
new Cmdln(<config>)
Create a Cmdln subclass instance. See the block comment
in the code for full documentation on the config
options.
CLI.prototype.do_<subcmd> = function (subcmd, opts, args, cb)
is how a
subcommand is defined. How the subcmd is handled can be customize with some
properties (e.g. options
, help
) on the handler function.
CLI.prototype.do_<subcmd> = <SubCLI>;
Instead of a function handler for a
subcommand, a do_<subcmd>
can be set to another Cmdln subclass to support
sub-subcommands, like git remote add|remove|rename|...
. See
"examples/fauxgit.js" for an example.
CLI.prototype.do_<subcmd>.aliases = <array of strings>;
to define one or
more aliases for a command. These aliases are shown in the "Commands:"
section of the generated help output.
CLI.prototype.do_<subcmd>.hiddenAliases = <array of strings>;
to define one
or more aliases for a command that are not shown in the generated help
output. This can be useful when renaming a subcommand in a new version of
a tool and still support the old name.
CLI.prototype.do_<subcmd>.options = <object>;
is how to set the options
(in dashdash format) for that
subcommand.
CLI.prototype.do_<subcmd>.helpOpts = <dashdash helpOpts object>;
to override
formatting settings for options
help output for this command. By default
the helpOpts
passed into the CLI constructor are used. The set of supported
helpOpts are defined by
dashdash.
CLI.prototype.do_<subcmd>.help = <string>;
to set the help string for a
subcommand. This supports some template variables:
{{name}}
becomes cli.name
(i.e. the tool name).{{cmd}}
becomes the sub-command name.CLI.prototype.do_<subcmd>.help = function (subcmd, opts, args, cb)
is
an alternate method to handle help for a subcommand. The given function
will be run when tool help <subcmd>
is called.
CLI.prototype.do_<subcmd>.desc = <string>;
can be set to a short string
to be used in the tool help
output to summarize subcmd. If not provided,
then the first line of do_<subcmd>.help
will be used.
CLI.prototype.do_<subcmd>.hidden = <boolean>;
Set to false to have
tool help
output not list this subcmd.
CLI.prototype.do_<subcmd>.interspersedOptions = <boolean>;
Set to
false to have tool <subcmd> ...
not allow interspersed options
(i.e. options after the first argument).
CLI.prototype.do_<subcmd>.allowUnknownOptions = <boolean>;
Set to
true to have tool <subcmd> ...
allow unknown options.
CLI.prototype.init(opts, args, cb)
Hook run after option processing
(this.opts
is set), but before the subcommand handler is run.
CLI.prototype.fini(subcmd, err, cb)
Hook run after the subcommand handler is
run. Here err
is the error returned by the invocation of the CLI. This allows
a fini
method to use or deal with that error, if necessary. To just
pass that err on (to the calling main
) do this:
CLI.prototype.fini = function fini(subcmd, err, cb) {
// Whatever finalization you want to do here (possibly with a
// `finiErr`) ...
cb(finiErr || err, subcmd);
};
(Note: The call signature to fini
changed in cmdln v3. See the changelog
in CHANGES.md.)
[Backward incompatible change] Change the signature of a <cmdln>.fini
method
from:
MyCLI.prototype.fini = function fini(subcmd, cb) {
to:
MyCLI.prototype.fini = function fini(subcmd, err, cb) {
where err
is the error returned by the invocation of the CLI. This allows
a fini
method to use or deal with that error, if necessary.
cli.showErrStack
boolean. Set to true to have cmdln.main()
, if used,
print a full stack on a shown error. When wanted, this is typically set
in If you want this option it is typically
set either
cli.handlerFromSubcmd(<subcmd>)
will return the appropriate
do_<subcmd>
method that handles the given sub-command. This resolves
sub-command aliases.
cli.helpFromSubcmd(<subcmd>)
will return the help string for
that subcmd or, if defined, the help function defined for that subcmd.
This is used by the default do_help
implementation.
cli.bashCompletion()
generates and returns bash completion for
the CLI.
cmdln.main()
This is a convenience method for driving the mainline of your script using
the your defined Cmdln
subclass. There are a number of options to control
how it works. Read the block comment on that function in "lib/cmdln.js" for
the best docs.
MIT. See LICENSE.txt
3.4.1
Cmdln.prototype.main
where it could callback twice if there was
an OptionError processing the top-level options. This wasn't noticed because
the commonly used cmdln.main()
function that calls it would process.exit
on the first callback.FAQs
helper lib for creating CLI tools with subcommands; think `git`, `svn`, `zfs`
The npm package cmdln receives a total of 1,158 weekly downloads. As such, cmdln popularity was classified as popular.
We found that cmdln demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
In an open letter, JavaScript community leaders urge Oracle to give up the JavaScript trademark, arguing that it has been effectively abandoned through nonuse.
Security News
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.