Features
- reimagined
process.argvparsing utility - framework for single or multiple command programs
- automatic
--helpcommand generation with multiple theming options - built in cli coloring
- chainable api
Quick Start Guide
Installation
The electron package is available through npm. It is recommended
that you add it to your project's package.json.
npm install electron
Parsing Arguments
The argument parsing utility can be used independently of the program
framework. Just pass the process.argv from any node modules and your
ready to go.
The following command execution...
$ node cli.js build --minify --out saved.min.js
Could be captured as so...
var argv = require('electron').argv();
// objects
argv.commands; // [ 'build' ]
argv.modes; // [ 'minify' ]
argv.params; // { out: 'saved.min.js' }
// helpers
argv.command('build'); // true
argv.mode('m', 'minify'); // true
argv.param('o', 'out'); // 'saved.min.js'
Recommend reading the "Argument Parsing Utility" section of this documentation to learn about the methodologies and specifics of each of the helpers.
Your First Program
To construct your first program, simply execute the electron export with a parameter of the namespace you wish to use for your program. Then proceed to define your settings and commands.
var myApp = require('../lib/myapp')
, program = require('electron')('myapp');
/**
* Define your program settings
*/
program
.name('My Cool App')
.desc('http://docs.mycoolapp.com')
.version(myApp.version);
/**
* Define your first command
*/
program
.command('build')
.desc('start a build task')
.option('-m, --minify', 'flag to set enable minification')
.option('-o, --out [file.js]', 'name of output file')
.action(function (argv) {
var minify = argv.mode('m', 'minify')
, savefile = argv.param('o', 'out')
, cwd = argv.cwd;
program.colorize();
console.log('Welcome to myApp'.gray + myApp.version);
console.log('It works if it ends with '.gray + 'myApp ' + 'ok'.green);
// etc...
});
/**
* Parse argv and execute respective command
*/
program.parse();
Your -h, --help and -v, --version will be generated for you automatically.
Recommend reading the "Program Framework" and "Constructing Commands" sections of this documentation to learn about all of the available chainable commands and theming options available to construct your programs.
Argument Parsing Utility
The electron argument parser takes the node.js standard
process.argv array and constructs an object with helpers
that can easily be queried. This helper is publicly exposed
so it can be used independant of the cli framework.
var electron = require('electron')
, argv = electron.argv(process.argv);
When constructed, the electron argv parser recognizes three types command line arguments: commands, modes, and parameters.
Each of these types also has a helper that will provide quick access to whether a command or mode is present, or the value of a parameter.
Commands
Commands are the simplest of arguments. They are any arguments
that are listed to that do not start with the - or -- prefix.
Essentially, they are a list of keys.
// $ node cli.js hello universe
argv.commands === [ 'hello', 'universe' ];
Modes
Modes are also a non-value list of keys, but they can be expressed
differently by using the - or -- prefix. When using modes, if
it begins with a single -, each letter will be parsed as its own mode.
// $ node cli.js --universe -abc
argv.modes === [ 'universe', 'a', 'b', 'c' ];
Parameters
Paremeters are key:value pairs that are declared in a similiar manner as modes. They can be declared in any of the following ways.
// $ node cli.js --noun unverse -v say --topic=hello -w=now
argv.params === {
noun: 'universe'
, v: 'say'
, topic: 'hello'
, w: 'now'
};
.command (cmd, [cmd], [...])
The command helper takes a list of commands and will
return true if any of them exist in the commands list.
// node cli.js hello universe
var greeting = argv.command('hi', 'hello') // true
, world = argv.command('world', 'earth'); // false
.mode (mode, [mode], [...])
The mode helper takes a list of modes and will
return true if any of them exist in the modes list.
// node cli.js --hello -abc
var greeting = argv.mode('h', 'hello') // true
, world = argv.mode('w', 'world'); // false
.param (param, [param], [...])
The param helper takes a list of parameters and will
return the value of the first parameter that matches, or
null if none of the parameters exist in the params list.
// node cli.js --hello universe
var greeting = argv.param('h', 'hello') // 'universe'
, world = argv.param('w', 'world'); // null
Program Framework
The primary export of the electron module is a function
that composes a new program framework. The returned
program is a chainable api that allow you to change
settings, define commands, and start launch the program.
The primary argument provided on construction is the base name used through the help documentation. In a majority of of cases, this would be the command executed from your terminal used launch the program.
In the case of scripts with the header of #!/usr/bin/env node,
you should use a variant of the following.
var program = electron('microscope');
If you are however launching your program from a .js file,
the recommended construction pattern is the following.
var program = electrong('node microscope.js');
You can then chain any of the following commands to further define your application and commands.
.command (name)
The most important aspect of an application is defining the different commands that can be executed for it. Some people prefer a CLI tool that does one thing based on a set of options. Others prefer a command line tool that can pivot based on a command string. Electron supports both.
When using the command method, it will return a constructed
command object with a different set of methods for chaining.
Please read the "Constructing Commands" section for all available
chainable methods and their respective purpose.
Single Command
As you understand how Electron parses command-line options,
you know that a command is any option that does
not start with - or --. Therefor, a single-command electron
application is one that does not require any commands, but
will execute a single action. Best demonstrated...
$ node app.js -p 8080
In the case of single-command applications, we will define
a default command for electron to run.
program
.command('default')
.action(function (argv) {
var port = argv.param('p', 'port');
// something cool
});
The default command will run when no commands are passed in,
but it will not run if a command is provided.
Multiple Commands
You can also create many different commands for your application
based on a simple string. These can be used in conjunction
with default if you would like.
$ node app.js hello --universe
In this case we want to only run an action when the comamnd
hello is present. This can easily be achieved.
program
.command('hello')
.action(fn);
There are also cases where you might want to have multipe layers of commands.
$ node app.js hello universe
Using the same mechanism, we can easily define this action.
program
.command('hello universe')
.action(fn);
One final option to explore with multiple commands is wildcards. Wildcards can exist at any level in a multi-word command, but they only work for entire words, not substrings.
program
.command('hello *')
.action(function (argv) {
var where = argv.commands[1];
});
Would respond for any command starting with hello and is two
commands long, such as...
$ node app.js hello world
$ node app.js hello universe
Absent Commands
Should you want to notify your users when they attempt to use
a command is not support, you may use the absent command. This
is also useful if you want to have a single command app but
support a list of items as "options", such as a list of files or
directories.
$ node build.js file1.js files2.js
program
.command('absent')
.action(function (argv) {
var files = argv.commands.slice(0);
// something cool
});
.parse (process.argv)
The parse method will initiate the program with
selection of arguments and run a matching action. It
should be used once all commands and settings have
been propogated.
program.parse();
program.parse(process.argv);
program.parse([ 'node', 'app.js', '--hello', '--universe' ]);
If no parameter is provided, parse will default to using
the current processes process.argv array. You may alse
provide your own array of commands if you like. Note that
argv parsing expectes the first item to be the executing program
and the second argument to be the script (as is with all node argv).
These will be discarded.
.name (name)
Provide a formal name to be used when displaying the help for the given program. Returns the program for chaining.
program.name('Electron Framework');
.version (version)
Provide a program version to be used when displaying the version for the given program. Returns the program for chaining.
program.version(electron.version);
.desc (description)
Provide a program discription to be used when displaying the the help for the given program. Returns the program for chaining.
program.desc('https://github.com/logicalparadox/electron');
.cwd (fqp)
Provide an alternative current working directory to be
passed as part of the argv parameter to the action that has
been executed. Returns the program for chaining.
// set
program.cwd(__dirname);
// get
program
.command('universe')
.action(function (argv) {
var cwd = argv.cwd;
// something cool
});
.theme (theme, specifications)
You may change the appearance of the --help using
a simple theming mechanism. Electron comes bundled with
two themes. Each theme also supports minor tweaks. Returns
the program for chaining.
clean (default)
A colorful and verbose theme useful for multi-command applications.
program
.theme('clean', {
noColor: false // set to true to disable color coding
, prefix: '' // prefix written before each line, such as 'help:'
});
simple
An "options only" theme useful for single command applications.
program
.theme('simple', {
noColor: false // set to true to disable color coding
, command: 'default' // which command to show options for
, usage: '<options>' // special usage instructions
});
Use Your Own Function
You may also provide a function to theme to provide your own output.
The following example will list all of the commands present in your
program.
program.theme(function () {
this.colorize();
console.log('Usage: %s <command>', this.opts.base);
this.commands.forEach(functioni (cmd) {
console.log(' %s - %s', cmd.cmd, cmd.desc);
});
});
Those interesting in building custom themes should view Electron on GitHub and explore lib/electron/themes.
.colorize ()
The colorize helper is available if you wish you implement
a colorized but lightweight logging mechanism in your actions,
or if you are building a custom help theme. colorize works
by extending String.prototype with a number of color options.
Just in case, if the current program is not running as a TTY,
no string changes will be made.
program.colorize();
console.log('hello universe'.green);
Colors
- red
- green
- yellow
- blue
- magenta
- cyan
- gray
Constructing Commands
Once you have decided to construct a command through program.command
you will be returned a command object that you can manipulate through
chainable methods.
.desc (description)
Provide a description for this command to be used when being display in help.
program
.command('hello universe')
.desc('Say "Hello" to the Universe.');
.option (opts, description, required)
You may define any number of options for
each command. The opts string expects a comma delimited
list of commands with an optional default value or
indicator surrounded by brackets. You may
also provide a description of the option and whether
it is required.
This command may be called multiple times to define multiple options.
program
.command('build')
.option('-m, --minify', 'Flag to build minify version')
.option('-f, --file [build.js]', 'Save filename', true);
.action (function)
Provide the action to be used should this command be
called. The function will receive one parameter of the
parsed process.argv object. Multiple calls to action will
replace the previous defined action.
program
.command('build')
.action(function (argv) {
var minify = argv.mode('m', 'minify')
, file = argv.param('f', 'file');
// go!
});