Skelleton extended.
This commit is contained in:
+1
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2010 Heather Arthur
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
# nomnom
|
||||
nomnom is an option parser for node. It noms your args and gives them back to you in a hash.
|
||||
|
||||
```javascript
|
||||
var opts = require("nomnom")
|
||||
.option('debug', {
|
||||
abbr: 'd',
|
||||
flag: true,
|
||||
help: 'Print debugging info'
|
||||
})
|
||||
.option('config', {
|
||||
abbr: 'c',
|
||||
default: 'config.json',
|
||||
help: 'JSON file with tests to run'
|
||||
})
|
||||
.option('version', {
|
||||
flag: true,
|
||||
help: 'print version and exit',
|
||||
callback: function() {
|
||||
return "version 1.2.4";
|
||||
}
|
||||
})
|
||||
.parse();
|
||||
|
||||
if (opts.debug)
|
||||
// do stuff
|
||||
```
|
||||
|
||||
You don't have to specify anything if you don't want to:
|
||||
|
||||
```javascript
|
||||
var opts = require("nomnom").parse();
|
||||
|
||||
var url = opts[0]; // get the first positional arg
|
||||
var file = opts.file // see if --file was specified
|
||||
var verbose = opts.v // see if -v was specified
|
||||
var extras = opts._ // get an array of the unmatched, positional args
|
||||
```
|
||||
|
||||
# Install
|
||||
for [node.js](http://nodejs.org/) and [npm](http://github.com/isaacs/npm):
|
||||
|
||||
npm install nomnom
|
||||
|
||||
# More Details
|
||||
Nomnom supports args like `-d`, `--debug`, `--no-debug`, `--file=test.txt`, `--file test.txt`, `-f test.txt`, `-xvf`, and positionals. Positionals are arguments that don't fit the `-a` or `--atomic` format and aren't attached to an option.
|
||||
|
||||
Values are JSON parsed, so `--debug=true --count=3 --file=log.txt` would give you:
|
||||
|
||||
```
|
||||
{
|
||||
"debug": true,
|
||||
"count": 3,
|
||||
"file": "log.txt"
|
||||
}
|
||||
```
|
||||
|
||||
# Commands
|
||||
Nomnom supports command-based interfaces (e.g. with git: `git add -p` and `git rebase -i` where `add` and `rebase` are the commands):
|
||||
|
||||
```javascript
|
||||
var parser = require("nomnom");
|
||||
|
||||
parser.command('browser')
|
||||
.callback(function(opts) {
|
||||
runBrowser(opts.url);
|
||||
})
|
||||
.help("run browser tests");
|
||||
|
||||
parser.command('sanity')
|
||||
.option('outfile', {
|
||||
abbr: 'o',
|
||||
help: "file to write results to"
|
||||
})
|
||||
.option('config', {
|
||||
abbr: 'c',
|
||||
default: 'config.json',
|
||||
help: "json manifest of tests to run"
|
||||
})
|
||||
.callback(function(opts) {
|
||||
runSanity(opts.filename);
|
||||
})
|
||||
.help("run the sanity tests")
|
||||
|
||||
parser.parse();
|
||||
```
|
||||
|
||||
Each command generates its own usage message when `-h` or `--help` is specified with the command.
|
||||
|
||||
# Usage
|
||||
Nomnom prints out a usage message if `--help` or `-h` is an argument. Usage for these options in `test.js`:
|
||||
|
||||
```javascript
|
||||
var opts = require("nomnom")
|
||||
.script("runtests")
|
||||
.options({
|
||||
path: {
|
||||
position: 0,
|
||||
help: "Test file to run",
|
||||
list: true
|
||||
},
|
||||
config: {
|
||||
abbr: 'c',
|
||||
metavar: 'FILE',
|
||||
help: "Config file with tests to run"
|
||||
},
|
||||
debug: {
|
||||
abbr: 'd',
|
||||
flag: true,
|
||||
help: "Print debugging info"
|
||||
}
|
||||
}).parse();
|
||||
```
|
||||
|
||||
...would look like this:
|
||||
|
||||
usage: runtests <path>... [options]
|
||||
|
||||
path Test file to run
|
||||
|
||||
options:
|
||||
-c FILE, --config FILE Config file with tests to run
|
||||
-d, --debug Print debugging info
|
||||
|
||||
# Options
|
||||
You can either add a specification for an option with `nomnom.option('name', spec)` or pass the specifications to `nomnom.options()` as a hash keyed on option name. Each option specification can have the following fields:
|
||||
|
||||
#### abbr and full
|
||||
`abbr` is the single character string to match to this option, `full` is the full-length string (defaults to the name of the option).
|
||||
|
||||
This option matches `-d` and `--debug` on the command line:
|
||||
|
||||
```javascript
|
||||
nomnom.option('debug', {
|
||||
abbr: 'd'
|
||||
})
|
||||
```
|
||||
|
||||
This option matches `-n 3`, `--num-lines 12` on the command line:
|
||||
|
||||
```javascript
|
||||
nomnom.option('numLines', {
|
||||
abbr: 'n',
|
||||
full: 'num-lines'
|
||||
})
|
||||
```
|
||||
|
||||
#### flag
|
||||
|
||||
If this is set to true, the option acts as a flag and doesn't swallow the next value on the command line. Default is `false`, so normally if you had a command line `--config test.js`, `config` would get a value of `test.js` in the options hash. Whereas if you specify:
|
||||
|
||||
```javascript
|
||||
nomnom.option('config', {
|
||||
flag: true
|
||||
})
|
||||
```
|
||||
|
||||
`config` would get a value of `true` in the options hash, and `test.js` would be a free positional arg.
|
||||
|
||||
#### metavar
|
||||
|
||||
`metavar` is used in the usage printout e.g. `"PATH"` in `"-f PATH, --file PATH"`.
|
||||
|
||||
#### string
|
||||
|
||||
A shorthand for `abbr`, `full`, and `metavar`. For example, to attach an option to `-c` and `--config` use a `string: "-c FILE, --config=FILE"`
|
||||
|
||||
#### help
|
||||
|
||||
A string description of the option for the usage printout.
|
||||
|
||||
#### default
|
||||
|
||||
The value to give the option if it's not specified in the arguments.
|
||||
|
||||
#### type
|
||||
|
||||
If you don't want the option JSON-parsed, specify type `"string"`.
|
||||
|
||||
#### callback
|
||||
|
||||
A callback that will be executed as soon as the option is encountered. If the callback returns a string it will print the string and exit:
|
||||
|
||||
```javascript
|
||||
nomnom.option('count', {
|
||||
callback: function(count) {
|
||||
if (count != parseInt(count)) {
|
||||
return "count must be an integer";
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### position
|
||||
|
||||
The position of the option if it's a positional argument. If the option should be matched to the first positional arg use position `0`, etc.
|
||||
|
||||
#### list
|
||||
|
||||
Specifies that the option is a list. Appending can be achieved by specifying the arg more than once on the command line:
|
||||
|
||||
node test.js --file=test1.js --file=test2.js
|
||||
|
||||
If the option has a `position` and `list` is `true`, all positional args including and after `position` will be appended to the array.
|
||||
|
||||
#### required
|
||||
|
||||
If this is set to `true` and the option isn't in the args, a message will be printed and the program will exit.
|
||||
|
||||
#### choices
|
||||
|
||||
A list of the possible values for the option (e.g. `['run', 'test', 'open']`). If the parsed value isn't in the list a message will be printed and the program will exit.
|
||||
|
||||
#### transform
|
||||
|
||||
A function that takes the value of the option as entered and returns a new value that will be seen as the value of the option.
|
||||
|
||||
```javascript
|
||||
nomnom.option('date', {
|
||||
abbr: 'd',
|
||||
transform: function(timestamp) {
|
||||
return new Date(timestamp);
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### hidden
|
||||
|
||||
Option won't be printed in the usage
|
||||
|
||||
|
||||
# Parser interface
|
||||
`require("nomnom")` will give you the option parser. You can also make an instance of a parser with `require("nomnom")()`. You can chain any of these functions off of a parser:
|
||||
|
||||
#### option
|
||||
|
||||
Add an option specification with the given name:
|
||||
|
||||
```javascript
|
||||
nomnom.option('debug', {
|
||||
abbr: 'd',
|
||||
flag: true,
|
||||
help: "Print debugging info"
|
||||
})
|
||||
```
|
||||
|
||||
#### options
|
||||
|
||||
Add options as a hash keyed by option name, good for a cli with tons of options like [this example](http://github.com/harthur/replace/blob/master/bin/replace.js):
|
||||
|
||||
```javascript
|
||||
nomnom.options({
|
||||
debug: {
|
||||
abbr: 'd',
|
||||
flag: true,
|
||||
help: "Print debugging info"
|
||||
},
|
||||
fruit: {
|
||||
help: "Fruit to buy"
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### usage
|
||||
|
||||
The string that will override the default generated usage message.
|
||||
|
||||
#### help
|
||||
|
||||
A string that is appended to the usage.
|
||||
|
||||
#### script
|
||||
|
||||
Nomnom can't detect the alias used to run your script. You can use `script` to provide the correct name for the usage printout instead of e.g. `node test.js`.
|
||||
|
||||
#### printer
|
||||
|
||||
Overrides the usage printing function.
|
||||
|
||||
#### command
|
||||
|
||||
Takes a command name and gives you a command object on which you can chain command options.
|
||||
|
||||
#### nocommand
|
||||
|
||||
Gives a command object that will be used when no command is called.
|
||||
|
||||
#### nocolors
|
||||
|
||||
Disables coloring of the usage message.
|
||||
|
||||
#### parse
|
||||
|
||||
Parses node's `process.argv` and returns the parsed options hash. You can also provide argv:
|
||||
|
||||
```javascript
|
||||
var opts = nomnom.parse(["-xvf", "--atomic=true"])
|
||||
```
|
||||
|
||||
#### nom
|
||||
|
||||
The same as `parse()`.
|
||||
|
||||
# Command interface
|
||||
A command is specified with `nomnom.command('name')`. All these functions can be chained on a command:
|
||||
|
||||
#### option
|
||||
|
||||
Add an option specifically for this command.
|
||||
|
||||
#### options
|
||||
|
||||
Add options for this command as a hash of options keyed by name.
|
||||
|
||||
#### callback
|
||||
|
||||
A callback that will be called with the parsed options when the command is used.
|
||||
|
||||
#### help
|
||||
|
||||
A help string describing the function of this command.
|
||||
|
||||
#### usage
|
||||
|
||||
Override the default generated usage string for this command.
|
||||
+584
@@ -0,0 +1,584 @@
|
||||
var _ = require("underscore"), chalk = require('chalk');
|
||||
|
||||
|
||||
function ArgParser() {
|
||||
this.commands = {}; // expected commands
|
||||
this.specs = {}; // option specifications
|
||||
}
|
||||
|
||||
ArgParser.prototype = {
|
||||
/* Add a command to the expected commands */
|
||||
command : function(name) {
|
||||
var command;
|
||||
if (name) {
|
||||
command = this.commands[name] = {
|
||||
name: name,
|
||||
specs: {}
|
||||
};
|
||||
}
|
||||
else {
|
||||
command = this.fallback = {
|
||||
specs: {}
|
||||
};
|
||||
}
|
||||
|
||||
// facilitates command('name').options().cb().help()
|
||||
var chain = {
|
||||
options : function(specs) {
|
||||
command.specs = specs;
|
||||
return chain;
|
||||
},
|
||||
opts : function(specs) {
|
||||
// old API
|
||||
return this.options(specs);
|
||||
},
|
||||
option : function(name, spec) {
|
||||
command.specs[name] = spec;
|
||||
return chain;
|
||||
},
|
||||
callback : function(cb) {
|
||||
command.cb = cb;
|
||||
return chain;
|
||||
},
|
||||
help : function(help) {
|
||||
command.help = help;
|
||||
return chain;
|
||||
},
|
||||
usage : function(usage) {
|
||||
command._usage = usage;
|
||||
return chain;
|
||||
}
|
||||
};
|
||||
return chain;
|
||||
},
|
||||
|
||||
nocommand : function() {
|
||||
return this.command();
|
||||
},
|
||||
|
||||
options : function(specs) {
|
||||
this.specs = specs;
|
||||
return this;
|
||||
},
|
||||
|
||||
opts : function(specs) {
|
||||
// old API
|
||||
return this.options(specs);
|
||||
},
|
||||
|
||||
globalOpts : function(specs) {
|
||||
// old API
|
||||
return this.options(specs);
|
||||
},
|
||||
|
||||
option : function(name, spec) {
|
||||
this.specs[name] = spec;
|
||||
return this;
|
||||
},
|
||||
|
||||
usage : function(usage) {
|
||||
this._usage = usage;
|
||||
return this;
|
||||
},
|
||||
|
||||
printer : function(print) {
|
||||
this.print = print;
|
||||
return this;
|
||||
},
|
||||
|
||||
script : function(script) {
|
||||
this._script = script;
|
||||
return this;
|
||||
},
|
||||
|
||||
scriptName : function(script) {
|
||||
// old API
|
||||
return this.script(script);
|
||||
},
|
||||
|
||||
help : function(help) {
|
||||
this._help = help;
|
||||
return this;
|
||||
},
|
||||
|
||||
colors: function() {
|
||||
// deprecated - colors are on by default now
|
||||
return this;
|
||||
},
|
||||
|
||||
nocolors : function() {
|
||||
this._nocolors = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
parseArgs : function(argv) {
|
||||
// old API
|
||||
return this.parse(argv);
|
||||
},
|
||||
|
||||
nom : function(argv) {
|
||||
return this.parse(argv);
|
||||
},
|
||||
|
||||
parse : function(argv) {
|
||||
this.print = this.print || function(str, code) {
|
||||
console.log(str);
|
||||
process.exit(code || 0);
|
||||
};
|
||||
this._help = this._help || "";
|
||||
this._script = this._script || process.argv[0] + " "
|
||||
+ require('path').basename(process.argv[1]);
|
||||
this.specs = this.specs || {};
|
||||
|
||||
var argv = argv || process.argv.slice(2);
|
||||
|
||||
var arg = Arg(argv[0]).isValue && argv[0],
|
||||
command = arg && this.commands[arg],
|
||||
commandExpected = !_(this.commands).isEmpty();
|
||||
|
||||
if (commandExpected) {
|
||||
if (command) {
|
||||
_(this.specs).extend(command.specs);
|
||||
this._script += " " + command.name;
|
||||
if (command.help) {
|
||||
this._help = command.help;
|
||||
}
|
||||
this.command = command;
|
||||
}
|
||||
else if (arg) {
|
||||
return this.print(this._script + ": no such command '" + arg + "'", 1);
|
||||
}
|
||||
else {
|
||||
// no command but command expected e.g. 'git -v'
|
||||
var helpStringBuilder = {
|
||||
list : function() {
|
||||
return 'one of: ' + _(this.commands).keys().join(", ");
|
||||
},
|
||||
twoColumn : function() {
|
||||
// find the longest command name to ensure horizontal alignment
|
||||
var maxLength = _(this.commands).max(function (cmd) {
|
||||
return cmd.name.length;
|
||||
}).name.length;
|
||||
|
||||
// create the two column text strings
|
||||
var cmdHelp = _.map(this.commands, function(cmd, name) {
|
||||
var diff = maxLength - name.length;
|
||||
var pad = new Array(diff + 4).join(" ");
|
||||
return " " + [ name, pad, cmd.help ].join(" ");
|
||||
});
|
||||
return "\n" + cmdHelp.join("\n");
|
||||
}
|
||||
};
|
||||
|
||||
// if there are a small number of commands and all have help strings,
|
||||
// display them in a two column table; otherwise use the brief version.
|
||||
// The arbitrary choice of "20" comes from the number commands git
|
||||
// displays as "common commands"
|
||||
var helpType = 'list';
|
||||
if (_(this.commands).size() <= 20) {
|
||||
if (_(this.commands).every(function (cmd) { return cmd.help; })) {
|
||||
helpType = 'twoColumn';
|
||||
}
|
||||
}
|
||||
|
||||
this.specs.command = {
|
||||
position: 0,
|
||||
help: helpStringBuilder[helpType].call(this)
|
||||
}
|
||||
|
||||
if (this.fallback) {
|
||||
_(this.specs).extend(this.fallback.specs);
|
||||
this._help = this.fallback.help;
|
||||
} else {
|
||||
this.specs.command.required = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.specs.length === undefined) {
|
||||
// specs is a hash not an array
|
||||
this.specs = _(this.specs).map(function(opt, name) {
|
||||
opt.name = name;
|
||||
return opt;
|
||||
});
|
||||
}
|
||||
this.specs = this.specs.map(function(opt) {
|
||||
return Opt(opt);
|
||||
});
|
||||
|
||||
if (argv.indexOf("--help") >= 0 || argv.indexOf("-h") >= 0) {
|
||||
return this.print(this.getUsage());
|
||||
}
|
||||
|
||||
var options = {};
|
||||
var args = argv.map(function(arg) {
|
||||
return Arg(arg);
|
||||
})
|
||||
.concat(Arg());
|
||||
|
||||
var positionals = [];
|
||||
|
||||
/* parse the args */
|
||||
var that = this;
|
||||
args.reduce(function(arg, val) {
|
||||
/* positional */
|
||||
if (arg.isValue) {
|
||||
positionals.push(arg.value);
|
||||
}
|
||||
else if (arg.chars) {
|
||||
var last = arg.chars.pop();
|
||||
|
||||
/* -cfv */
|
||||
(arg.chars).forEach(function(ch) {
|
||||
that.setOption(options, ch, true);
|
||||
});
|
||||
|
||||
/* -v key */
|
||||
if (!that.opt(last).flag) {
|
||||
if (val.isValue) {
|
||||
that.setOption(options, last, val.value);
|
||||
return Arg(); // skip next turn - swallow arg
|
||||
}
|
||||
else {
|
||||
that.print("'-" + (that.opt(last).name || last) + "'"
|
||||
+ " expects a value\n\n" + that.getUsage(), 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* -v */
|
||||
that.setOption(options, last, true);
|
||||
}
|
||||
|
||||
}
|
||||
else if (arg.full) {
|
||||
var value = arg.value;
|
||||
|
||||
/* --key */
|
||||
if (value === undefined) {
|
||||
/* --key value */
|
||||
if (!that.opt(arg.full).flag) {
|
||||
if (val.isValue) {
|
||||
that.setOption(options, arg.full, val.value);
|
||||
return Arg();
|
||||
}
|
||||
else {
|
||||
that.print("'--" + (that.opt(arg.full).name || arg.full) + "'"
|
||||
+ " expects a value\n\n" + that.getUsage(), 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* --flag */
|
||||
value = true;
|
||||
}
|
||||
}
|
||||
that.setOption(options, arg.full, value);
|
||||
}
|
||||
return val;
|
||||
});
|
||||
|
||||
positionals.forEach(function(pos, index) {
|
||||
this.setOption(options, index, pos);
|
||||
}, this);
|
||||
|
||||
options._ = positionals;
|
||||
|
||||
this.specs.forEach(function(opt) {
|
||||
if (opt.default !== undefined && options[opt.name] === undefined) {
|
||||
options[opt.name] = opt.default;
|
||||
}
|
||||
}, this);
|
||||
|
||||
// exit if required arg isn't present
|
||||
this.specs.forEach(function(opt) {
|
||||
if (opt.required && options[opt.name] === undefined) {
|
||||
var msg = opt.name + " argument is required";
|
||||
msg = this._nocolors ? msg : chalk.red(msg);
|
||||
|
||||
this.print("\n" + msg + "\n" + this.getUsage(), 1);
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (command && command.cb) {
|
||||
command.cb(options);
|
||||
}
|
||||
else if (this.fallback && this.fallback.cb) {
|
||||
this.fallback.cb(options);
|
||||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
|
||||
getUsage : function() {
|
||||
if (this.command && this.command._usage) {
|
||||
return this.command._usage;
|
||||
}
|
||||
else if (this.fallback && this.fallback._usage) {
|
||||
return this.fallback._usage;
|
||||
}
|
||||
if (this._usage) {
|
||||
return this._usage;
|
||||
}
|
||||
|
||||
// todo: use a template
|
||||
var str = "\n"
|
||||
if (!this._nocolors) {
|
||||
str += chalk.bold("Usage:");
|
||||
}
|
||||
else {
|
||||
str += "Usage:";
|
||||
}
|
||||
str += " " + this._script;
|
||||
|
||||
var positionals = _(this.specs).select(function(opt) {
|
||||
return opt.position != undefined;
|
||||
})
|
||||
positionals = _(positionals).sortBy(function(opt) {
|
||||
return opt.position;
|
||||
});
|
||||
var options = _(this.specs).select(function(opt) {
|
||||
return opt.position === undefined;
|
||||
});
|
||||
|
||||
// assume there are no gaps in the specified pos. args
|
||||
positionals.forEach(function(pos) {
|
||||
str += " ";
|
||||
var posStr = pos.string;
|
||||
if (!posStr) {
|
||||
posStr = pos.name || "arg" + pos.position;
|
||||
if (pos.required) {
|
||||
posStr = "<" + posStr + ">";
|
||||
} else {
|
||||
posStr = "[" + posStr + "]";
|
||||
}
|
||||
if (pos.list) {
|
||||
posStr += "...";
|
||||
}
|
||||
}
|
||||
str += posStr;
|
||||
});
|
||||
|
||||
if (options.length) {
|
||||
if (!this._nocolors) {
|
||||
// must be a better way to do this
|
||||
str += chalk.blue(" [options]");
|
||||
}
|
||||
else {
|
||||
str += " [options]";
|
||||
}
|
||||
}
|
||||
|
||||
if (options.length || positionals.length) {
|
||||
str += "\n\n";
|
||||
}
|
||||
|
||||
function spaces(length) {
|
||||
var spaces = "";
|
||||
for (var i = 0; i < length; i++) {
|
||||
spaces += " ";
|
||||
}
|
||||
return spaces;
|
||||
}
|
||||
var longest = positionals.reduce(function(max, pos) {
|
||||
return pos.name.length > max ? pos.name.length : max;
|
||||
}, 0);
|
||||
|
||||
positionals.forEach(function(pos) {
|
||||
var posStr = pos.string || pos.name;
|
||||
str += posStr + spaces(longest - posStr.length) + " ";
|
||||
if (!this._nocolors) {
|
||||
str += chalk.grey(pos.help || "")
|
||||
}
|
||||
else {
|
||||
str += (pos.help || "")
|
||||
}
|
||||
str += "\n";
|
||||
}, this);
|
||||
if (positionals.length && options.length) {
|
||||
str += "\n";
|
||||
}
|
||||
|
||||
if (options.length) {
|
||||
if (!this._nocolors) {
|
||||
str += chalk.blue("Options:");
|
||||
}
|
||||
else {
|
||||
str += "Options:";
|
||||
}
|
||||
str += "\n"
|
||||
|
||||
var longest = options.reduce(function(max, opt) {
|
||||
return opt.string.length > max && !opt.hidden ? opt.string.length : max;
|
||||
}, 0);
|
||||
|
||||
options.forEach(function(opt) {
|
||||
if (!opt.hidden) {
|
||||
str += " " + opt.string + spaces(longest - opt.string.length) + " ";
|
||||
|
||||
var defaults = (opt.default != null ? " [" + opt.default + "]" : "");
|
||||
var help = opt.help ? opt.help + defaults : "";
|
||||
str += this._nocolors ? help: chalk.grey(help);
|
||||
|
||||
str += "\n";
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (this._help) {
|
||||
str += "\n" + this._help;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
ArgParser.prototype.opt = function(arg) {
|
||||
// get the specified opt for this parsed arg
|
||||
var match = Opt({});
|
||||
this.specs.forEach(function(opt) {
|
||||
if (opt.matches(arg)) {
|
||||
match = opt;
|
||||
}
|
||||
});
|
||||
return match;
|
||||
};
|
||||
|
||||
ArgParser.prototype.setOption = function(options, arg, value) {
|
||||
var option = this.opt(arg);
|
||||
if (option.callback) {
|
||||
var message = option.callback(value);
|
||||
|
||||
if (typeof message == "string") {
|
||||
this.print(message, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (option.type != "string") {
|
||||
try {
|
||||
// infer type by JSON parsing the string
|
||||
value = JSON.parse(value)
|
||||
}
|
||||
catch(e) {}
|
||||
}
|
||||
|
||||
if (option.transform) {
|
||||
value = option.transform(value);
|
||||
}
|
||||
|
||||
var name = option.name || arg;
|
||||
if (option.choices && option.choices.indexOf(value) == -1) {
|
||||
this.print(name + " must be one of: " + option.choices.join(", "), 1);
|
||||
}
|
||||
|
||||
if (option.list) {
|
||||
if (!options[name]) {
|
||||
options[name] = [value];
|
||||
}
|
||||
else {
|
||||
options[name].push(value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
options[name] = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* an arg is an item that's actually parsed from the command line
|
||||
e.g. "-l", "log.txt", or "--logfile=log.txt" */
|
||||
var Arg = function(str) {
|
||||
var abbrRegex = /^\-(\w+?)$/,
|
||||
fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
|
||||
valRegex = /^[^\-].*/;
|
||||
|
||||
var charMatch = abbrRegex.exec(str),
|
||||
chars = charMatch && charMatch[1].split("");
|
||||
|
||||
var fullMatch = fullRegex.exec(str),
|
||||
full = fullMatch && fullMatch[2];
|
||||
|
||||
var isValue = str !== undefined && (str === "" || valRegex.test(str));
|
||||
var value;
|
||||
if (isValue) {
|
||||
value = str;
|
||||
}
|
||||
else if (full) {
|
||||
value = fullMatch[1] ? false : fullMatch[3];
|
||||
}
|
||||
|
||||
return {
|
||||
str: str,
|
||||
chars: chars,
|
||||
full: full,
|
||||
value: value,
|
||||
isValue: isValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* an opt is what's specified by the user in opts hash */
|
||||
var Opt = function(opt) {
|
||||
var strings = (opt.string || "").split(","),
|
||||
abbr, full, metavar;
|
||||
for (var i = 0; i < strings.length; i++) {
|
||||
var string = strings[i].trim(),
|
||||
matches;
|
||||
if (matches = string.match(/^\-([^-])(?:\s+(.*))?$/)) {
|
||||
abbr = matches[1];
|
||||
metavar = matches[2];
|
||||
}
|
||||
else if (matches = string.match(/^\-\-(.+?)(?:[=\s]+(.+))?$/)) {
|
||||
full = matches[1];
|
||||
metavar = metavar || matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
matches = matches || [];
|
||||
var abbr = opt.abbr || abbr, // e.g. v from -v
|
||||
full = opt.full || full, // e.g. verbose from --verbose
|
||||
metavar = opt.metavar || metavar; // e.g. PATH from '--config=PATH'
|
||||
|
||||
var string;
|
||||
if (opt.string) {
|
||||
string = opt.string;
|
||||
}
|
||||
else if (opt.position === undefined) {
|
||||
string = "";
|
||||
if (abbr) {
|
||||
string += "-" + abbr;
|
||||
if (metavar)
|
||||
string += " " + metavar
|
||||
string += ", ";
|
||||
}
|
||||
string += "--" + (full || opt.name);
|
||||
if (metavar) {
|
||||
string += " " + metavar;
|
||||
}
|
||||
}
|
||||
|
||||
opt = _(opt).extend({
|
||||
name: opt.name || full || abbr,
|
||||
string: string,
|
||||
abbr: abbr,
|
||||
full: full,
|
||||
metavar: metavar,
|
||||
matches: function(arg) {
|
||||
return opt.full == arg || opt.abbr == arg || opt.position == arg
|
||||
|| opt.name == arg || (opt.list && arg >= opt.position);
|
||||
}
|
||||
});
|
||||
return opt;
|
||||
}
|
||||
|
||||
|
||||
var createParser = function() {
|
||||
return new ArgParser();
|
||||
}
|
||||
|
||||
var nomnom = createParser();
|
||||
|
||||
for (var i in nomnom) {
|
||||
if (typeof nomnom[i] == "function") {
|
||||
createParser[i] = _(nomnom[i]).bind(nomnom);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = createParser;
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
diff --git a/test/values.js b/test/values.js
|
||||
index efad789..7fa1078 100644
|
||||
--- a/test/values.js
|
||||
+++ b/test/values.js
|
||||
@@ -26,6 +26,12 @@ var opts = {
|
||||
},
|
||||
def2: {
|
||||
default: "val1"
|
||||
+ },
|
||||
+ "2d": {
|
||||
+ flag: true
|
||||
+ },
|
||||
+ "3d": {
|
||||
+ abbr: "3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +86,12 @@ exports.testDash = function(test) {
|
||||
};
|
||||
|
||||
exports.testNumbers = function(test) {
|
||||
- var options = parser.parseArgs(['sum', '-1', '2.5', '-3.5', '4']);
|
||||
+ var options = parser.parseArgs(['sum', '-1', '2.5', '-3.5', '4', '--2d', '-3', 'test']);
|
||||
|
||||
test.deepEqual(options.list3, ['-1', '2.5', '-3.5', '4']);
|
||||
+ test.strictEqual(options['2d'], true);
|
||||
+ test.strictEqual(options['3d'], "test")
|
||||
test.done();
|
||||
};
|
||||
+
|
||||
+
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
{
|
||||
"raw": "nomnom@^1.5.x",
|
||||
"scope": null,
|
||||
"escapedName": "nomnom",
|
||||
"name": "nomnom",
|
||||
"rawSpec": "^1.5.x",
|
||||
"spec": ">=1.5.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"/Users/gerrit/Documents/dev/nodejs/rentfor.camp/html/RentForCamp/node_modules/jsonlint"
|
||||
]
|
||||
],
|
||||
"_from": "nomnom@>=1.5.0 <2.0.0",
|
||||
"_id": "nomnom@1.8.1",
|
||||
"_inCache": true,
|
||||
"_location": "/nomnom",
|
||||
"_npmUser": {
|
||||
"name": "harth",
|
||||
"email": "fayearthur@gmail.com"
|
||||
},
|
||||
"_npmVersion": "1.4.3",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"raw": "nomnom@^1.5.x",
|
||||
"scope": null,
|
||||
"escapedName": "nomnom",
|
||||
"name": "nomnom",
|
||||
"rawSpec": "^1.5.x",
|
||||
"spec": ">=1.5.0 <2.0.0",
|
||||
"type": "range"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/jsonlint"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz",
|
||||
"_shasum": "2151f722472ba79e50a76fc125bb8c8f2e4dc2a7",
|
||||
"_shrinkwrap": null,
|
||||
"_spec": "nomnom@^1.5.x",
|
||||
"_where": "/Users/gerrit/Documents/dev/nodejs/rentfor.camp/html/RentForCamp/node_modules/jsonlint",
|
||||
"author": {
|
||||
"name": "Heather Arthur",
|
||||
"email": "fayearthur@gmail.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/harthur/nomnom/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "~0.4.0",
|
||||
"underscore": "~1.6.0"
|
||||
},
|
||||
"deprecated": "Package no longer supported. Contact support@npmjs.com for more info.",
|
||||
"description": "Option parser with generated usage and commands",
|
||||
"devDependencies": {
|
||||
"nodeunit": "~0.7.4"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"shasum": "2151f722472ba79e50a76fc125bb8c8f2e4dc2a7",
|
||||
"tarball": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz"
|
||||
},
|
||||
"homepage": "https://github.com/harthur/nomnom",
|
||||
"keywords": [
|
||||
"arguments",
|
||||
"option parser",
|
||||
"command line",
|
||||
"options",
|
||||
"parser"
|
||||
],
|
||||
"main": "./nomnom",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "harth",
|
||||
"email": "fayearthur@gmail.com"
|
||||
}
|
||||
],
|
||||
"name": "nomnom",
|
||||
"optionalDependencies": {},
|
||||
"readme": "ERROR: No README data found!",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/harthur/nomnom.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "nodeunit test/*.js"
|
||||
},
|
||||
"version": "1.8.1"
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
var opts = require("./nomnom")
|
||||
.option('debug', {
|
||||
abbr: 'd',
|
||||
flag: true,
|
||||
help: 'Print debugging info'
|
||||
})
|
||||
.option('config', {
|
||||
abbr: 'c',
|
||||
default: 'config.json',
|
||||
help: 'JSON file with tests to run'
|
||||
})
|
||||
.option('version', {
|
||||
flag: true,
|
||||
help: 'print version and exit',
|
||||
callback: function() {
|
||||
return "version 1.2.4";
|
||||
}
|
||||
})
|
||||
.parse();
|
||||
|
||||
if (opts.debug) {
|
||||
console.log("debug")
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
exports.testVersion = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
date: {
|
||||
callback: function(date) {
|
||||
test.equal(date, "2010-02-03", "date should match value")
|
||||
}
|
||||
}
|
||||
}).parse(["--date=2010-02-03"]);
|
||||
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testReturnString = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
version: {
|
||||
flag: true,
|
||||
callback: function() {
|
||||
return "v0.3";
|
||||
}
|
||||
}
|
||||
})
|
||||
.printer(function(string) {
|
||||
test.equal(0, string.indexOf("v0.3"))
|
||||
test.done();
|
||||
})
|
||||
.parse(["--version"]);
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
function strip(str) {
|
||||
return str.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
exports.testCallback = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
var parser = nomnom();
|
||||
parser.command('run').callback(function(options) {
|
||||
test.equal(options.v, 3);
|
||||
});
|
||||
parser.command('other').callback(function() {
|
||||
test.ok(false, "callback for other command shouldn't be called");
|
||||
});
|
||||
|
||||
parser.parse(["run","-v", "3"]);
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testMissingCommand = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
var parser = nomnom().scriptName("test");
|
||||
|
||||
parser.command('run');
|
||||
|
||||
parser.printer(function(string) {
|
||||
test.equal(string, "test: no such command 'other'");
|
||||
test.done();
|
||||
});
|
||||
|
||||
parser.parse(["other"]);
|
||||
}
|
||||
|
||||
exports.testNoCommand = function(test) {
|
||||
test.expect(2);
|
||||
|
||||
var parser = nomnom();
|
||||
|
||||
parser.nocommand()
|
||||
.options({
|
||||
version: {
|
||||
flag: true
|
||||
}
|
||||
})
|
||||
.callback(function(options) {
|
||||
test.strictEqual(options.version, true);
|
||||
})
|
||||
.usage("fallback usage");
|
||||
|
||||
parser.command('run');
|
||||
|
||||
var options = parser.parse(["--version"]);
|
||||
|
||||
test.strictEqual(options.version, true);
|
||||
test.done();
|
||||
}
|
||||
|
||||
function createParser() {
|
||||
var parser = nomnom().scriptName("test")
|
||||
.options({
|
||||
debug: {
|
||||
flag: true
|
||||
}
|
||||
});
|
||||
|
||||
parser.command('run')
|
||||
.options({
|
||||
file: {
|
||||
help: 'file to run'
|
||||
}
|
||||
})
|
||||
.help("run all");
|
||||
|
||||
parser.command('test').usage("test usage");
|
||||
|
||||
parser.nocommand()
|
||||
.options({
|
||||
verbose: {
|
||||
flag: true
|
||||
}
|
||||
})
|
||||
.help("nocommand");
|
||||
|
||||
return parser;
|
||||
}
|
||||
|
||||
exports.testUsage = function(test) {
|
||||
test.expect(4);
|
||||
|
||||
var parser = createParser();
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), "testusage");
|
||||
});
|
||||
parser.parse(["test", "-h"]);
|
||||
|
||||
parser = createParser().nocolors();
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), "Usage:testrun[options]Options:--debug--filefiletorunrunall");
|
||||
});
|
||||
parser.parse(["run", "-h"]);
|
||||
|
||||
parser = createParser().nocolors();
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), "Usage:test[command][options]commandoneof:run,testOptions:--debug--verbosenocommand");
|
||||
});
|
||||
parser.parse(["-h"]);
|
||||
|
||||
parser = createParser().nocolors();
|
||||
parser.nocommand()
|
||||
.usage("fallback");
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), "fallback");
|
||||
});
|
||||
parser.parse(["-h"]);
|
||||
|
||||
test.done();
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
var opts = {
|
||||
file: {
|
||||
position: 0,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
|
||||
var parser = nomnom().options(opts);
|
||||
|
||||
exports.testFlag = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
file: {
|
||||
position: 0,
|
||||
}
|
||||
})
|
||||
.printer(function(string) {
|
||||
test.equal(0, string.indexOf("'--key1' expects a value"))
|
||||
test.done();
|
||||
})
|
||||
.parse(["--key1"]);
|
||||
}
|
||||
|
||||
exports.testRequired = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
file: {
|
||||
required: true
|
||||
}
|
||||
})
|
||||
.printer(function(string) {
|
||||
test.equal(0, string.trim().indexOf("file argument is required"))
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse([]);
|
||||
}
|
||||
|
||||
exports.testChoices = function(test) {
|
||||
test.expect(2);
|
||||
|
||||
var parser = nomnom().options({
|
||||
color: {
|
||||
choices: ['green', 'blue']
|
||||
}
|
||||
})
|
||||
.printer(function(string) {
|
||||
test.equal(0, string.indexOf("color must be one of: green, blue"))
|
||||
});
|
||||
|
||||
parser.parse(['--color', 'red']);
|
||||
|
||||
var options = parser.parse(['--color', 'green']);
|
||||
test.equal(options.color, 'green');
|
||||
test.done();
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
var opts = {
|
||||
pos1: {
|
||||
position: 0
|
||||
},
|
||||
pos2: {
|
||||
position: 1
|
||||
},
|
||||
flag1: {
|
||||
flag: true
|
||||
},
|
||||
debug: {
|
||||
abbr: 'd'
|
||||
},
|
||||
numLines: {
|
||||
abbr: 'n',
|
||||
full: 'num-lines'
|
||||
},
|
||||
version: {
|
||||
string: '-v, --version'
|
||||
},
|
||||
config: {
|
||||
string: '-c FILE, --config=FILE'
|
||||
},
|
||||
skey : {
|
||||
string: '-k val'
|
||||
},
|
||||
skey2: {
|
||||
string: '-k2 val2, --key2 val2'
|
||||
},
|
||||
skey3: {
|
||||
string: '--key3=val'
|
||||
},
|
||||
skey4: {
|
||||
string: '--key4=val, -y val'
|
||||
}
|
||||
}
|
||||
|
||||
var parser = nomnom().options(opts);
|
||||
|
||||
exports.testPositional = function(test) {
|
||||
var options = parser.parse(["--flag1", "val1", "--config", "file", "val2"]);
|
||||
|
||||
test.equal(options.pos1, "val1");
|
||||
test.equal(options.pos2, "val2");
|
||||
test.deepEqual(options._, ["val1", "val2"])
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testAbbr = function(test) {
|
||||
var options = parser.parse(["-d", "yes", "--num-lines", "3"]);
|
||||
|
||||
test.equal(options.debug, "yes")
|
||||
test.equal(options.numLines, 3)
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testString = function(test) {
|
||||
var options = parser.parse(["-k", "val", "--config=test.js",
|
||||
"--key2", "val2", "--key3", "val3", "--key4=val4", "-v", "v0.3"]);
|
||||
|
||||
test.equal(options.version, "v0.3")
|
||||
test.equal(options.config, "test.js")
|
||||
test.equal(options.skey, "val")
|
||||
test.equal(options.skey2, "val2")
|
||||
test.equal(options.skey3, "val3")
|
||||
test.equal(options.skey4, "val4")
|
||||
test.done();
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
var parser = nomnom()
|
||||
.option('debug', {
|
||||
abbr: 'x',
|
||||
flag: true,
|
||||
help: 'Print debugging info'
|
||||
})
|
||||
.option('config', {
|
||||
abbr: 'c',
|
||||
default: 'config.json',
|
||||
help: 'JSON file with tests to run'
|
||||
})
|
||||
.option('version', {
|
||||
flag: true,
|
||||
help: 'print version and exit',
|
||||
callback: function() {
|
||||
return "version 1.2.4";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
exports.testOption = function(test) {
|
||||
var opts = parser.parse(["-x", "--no-verbose"]);
|
||||
|
||||
test.strictEqual(opts.debug, true);
|
||||
test.equal(opts.config, "config.json");
|
||||
test.done();
|
||||
}
|
||||
|
||||
|
||||
exports.testCommandOption = function(test) {
|
||||
var parser = nomnom()
|
||||
parser.command('test')
|
||||
.option('fruit', {
|
||||
abbr: 'f',
|
||||
flag: true
|
||||
})
|
||||
|
||||
var opts = parser.parse(["test", "-f"]);
|
||||
|
||||
test.strictEqual(opts.fruit, true);
|
||||
test.done();
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
var parser = nomnom()
|
||||
.option("addr", {
|
||||
abbr: "a",
|
||||
help: "host:port address",
|
||||
transform: function(value) {
|
||||
var parts = value.split(":");
|
||||
return {host: parts[0], port: Number(parts[1])};
|
||||
}
|
||||
})
|
||||
.option("string", {
|
||||
abbr: "s",
|
||||
help: "always a string",
|
||||
transform: function(value) {
|
||||
return value.toString();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
exports.testTransformComplexValue = function(test) {
|
||||
var opts = parser.parse(["-a", "localhost:1234"]);
|
||||
|
||||
test.strictEqual(opts.addr.host, "localhost");
|
||||
test.strictEqual(opts.addr.port, 1234);
|
||||
test.done();
|
||||
};
|
||||
|
||||
|
||||
exports.testTransformString = function(test) {
|
||||
var opts = parser.parse(["-s", "3"]);
|
||||
|
||||
test.strictEqual(opts.string, "3");
|
||||
test.done();
|
||||
};
|
||||
|
||||
|
||||
exports.testTransformCommand = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
var parser = nomnom().scriptName("test")
|
||||
.options({
|
||||
addr: {
|
||||
transform: function(value) {
|
||||
var parts = value.split(":");
|
||||
return {host: parts[0], port: Number(parts[1])};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
parser.command("run")
|
||||
.options({
|
||||
string: {
|
||||
transform: function(value) {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
})
|
||||
.callback(function(options) {
|
||||
test.strictEqual(options.string, "true");
|
||||
});
|
||||
|
||||
parser.parse(["run", "--string=true"]);
|
||||
test.done();
|
||||
};
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
function strip(str) {
|
||||
return str.replace(/\s+/g, '');
|
||||
};
|
||||
|
||||
var opts = {
|
||||
apple: {
|
||||
abbr: 'a',
|
||||
help: 'how many apples'
|
||||
},
|
||||
|
||||
banana: {
|
||||
full: "b-nana"
|
||||
},
|
||||
|
||||
carrot: {
|
||||
string: '-c NUM, --carrots=NUM'
|
||||
},
|
||||
|
||||
dill: {
|
||||
metavar: 'PICKLE'
|
||||
},
|
||||
|
||||
egg: {
|
||||
position: 0,
|
||||
help: 'robin'
|
||||
}
|
||||
}
|
||||
|
||||
var parser = nomnom().options(opts).help("all the best foods").scriptName("test").nocolors();
|
||||
|
||||
var expected = "Usage:test[egg][options]eggrobinOptions:-a,--applehowmanyapples--b-nana-cNUM,--carrots=NUM--dillPICKLEallthebestfoods"
|
||||
|
||||
exports.testH = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), expected)
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["-h"]);
|
||||
}
|
||||
|
||||
exports.testHelp = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
parser.printer(function(string) {
|
||||
test.equal(strip(string), expected)
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["--help"]);
|
||||
}
|
||||
|
||||
exports.testScriptName = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom()
|
||||
.script("test")
|
||||
.printer(function(string) {
|
||||
test.equal(strip(string),"Usage:test")
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["-h"]);
|
||||
}
|
||||
|
||||
exports.testUsage = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
parser
|
||||
.usage("test usage")
|
||||
.printer(function(string) {
|
||||
test.equal(string, "test usage")
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["--help"]);
|
||||
}
|
||||
|
||||
exports.testHidden = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
file: {
|
||||
hidden: true
|
||||
}
|
||||
})
|
||||
.scriptName("test")
|
||||
.printer(function(string) {
|
||||
test.equal(strip("Usage:test[options]Options:"), strip(string))
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["-h"]);
|
||||
}
|
||||
|
||||
exports.testRequiredOptional = function(test) {
|
||||
test.expect(1);
|
||||
|
||||
nomnom().options({
|
||||
foo: {
|
||||
position: 0,
|
||||
required: true,
|
||||
help: 'The foo'
|
||||
},
|
||||
bar: {
|
||||
position: 1,
|
||||
help: 'The bar'
|
||||
}
|
||||
})
|
||||
.scriptName("test")
|
||||
.printer(function(string) {
|
||||
test.equal(strip("Usage:test<foo>[bar]fooThefoobarThebar"), strip(string))
|
||||
test.done();
|
||||
})
|
||||
.nocolors()
|
||||
.parse(["-h"]);
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
var nomnom = require("../nomnom");
|
||||
|
||||
var opts = {
|
||||
debug: {
|
||||
flag: true
|
||||
},
|
||||
verbose: {
|
||||
flag: true,
|
||||
default: true
|
||||
},
|
||||
list1: {
|
||||
list: true
|
||||
},
|
||||
list2: {
|
||||
list: true
|
||||
},
|
||||
list3: {
|
||||
position: 1,
|
||||
list: true
|
||||
},
|
||||
num1: {
|
||||
type: "string"
|
||||
},
|
||||
def1: {
|
||||
default: "val1"
|
||||
},
|
||||
def2: {
|
||||
default: "val1"
|
||||
}
|
||||
}
|
||||
|
||||
var parser = nomnom().options(opts);
|
||||
|
||||
exports.testFlag = function(test) {
|
||||
var options = parser.parse(["--debug", "pos0", "--no-verbose"]);
|
||||
|
||||
test.strictEqual(options.debug, true);
|
||||
test.strictEqual(options.verbose, false);
|
||||
test.equal(options[0], "pos0");
|
||||
test.equal(options._[0], "pos0");
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testList = function(test) {
|
||||
var options = parser.parse(["pos0", "pos1", "--list1=val0", "--list2", "val1",
|
||||
"--list2", "val2", "pos2"]);
|
||||
|
||||
test.deepEqual(options.list1, ["val0"]);
|
||||
test.deepEqual(options.list2, ["val1", "val2"]);
|
||||
test.deepEqual(options.list3, ["pos1", "pos2"]);
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testDefault = function(test) {
|
||||
var options = parser.parse(["--def2", "val2", "--def3", "val3"]);
|
||||
|
||||
test.strictEqual(options.def1, "val1");
|
||||
test.strictEqual(options.def2, "val2");
|
||||
test.strictEqual(options.def3, "val3");
|
||||
test.done();
|
||||
}
|
||||
|
||||
exports.testTypes = function(test) {
|
||||
var options = parser.parseArgs(["", "-x", "3.14", "-w", "true", "-q", "120",
|
||||
"--num1", "4"]);
|
||||
|
||||
test.strictEqual(options[0], "");
|
||||
test.strictEqual(options.x, 3.14);
|
||||
test.strictEqual(options.w, true);
|
||||
test.strictEqual(options.q, 120);
|
||||
test.strictEqual(options.num1, "4");
|
||||
test.done();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user