Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Commit

Permalink
an opt can specify a callback
Browse files Browse the repository at this point in the history
  • Loading branch information
harthur committed Apr 18, 2011
1 parent 98697eb commit 8293e17
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 40 deletions.
63 changes: 41 additions & 22 deletions README.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ nomnom is an option parser for node and CommonJS. It noms your args and gives th


var options = require("nomnom") var options = require("nomnom")
.opts({ .opts({
debug: {
string: '-d, --debug',
help: 'Print debugging info'
},
config: { config: {
string: '-c PATH, --config=PATH', string: '-c PATH, --config=PATH',
default: 'config.json', default: 'config.json',
help: 'JSON file with tests to run' help: 'JSON file with tests to run'
},
debug: {
string: '-d, --debug',
help: 'Print debugging info'
} }
}) })
.parseArgs(); .parseArgs();
Expand All @@ -34,13 +34,12 @@ for [node.js](http://nodejs.org/) and [npm](http://github.com/isaacs/npm):
# Commands # Commands
Nomnom supports command-based interfaces, e.g. with git: `git add -p` and `git rebase -i` where `add` and `rebase` are the commands: Nomnom supports command-based interfaces, e.g. with git: `git add -p` and `git rebase -i` where `add` and `rebase` are the commands:


var parser = require("nomnom") var parser = nomnom.opts({
.opts({ // global opts debug: {
debug: { string: '-d, --debug',
string: '-d, --debug', help: 'print debugging info'
help: 'print debugging info' }
} });
});


parser.command('sanity') parser.command('sanity')
.opts({ .opts({
Expand Down Expand Up @@ -72,24 +71,44 @@ By default, nomnom parses [node](http://nodejs.org/)'s `process.argv`. You can a


Values are JSON parsed, so `--debug=true --count=3 --file=log.txt` would give you: Values are JSON parsed, so `--debug=true --count=3 --file=log.txt` would give you:


{ debug: true, {
count: 3, "debug": true,
file: "log.txt" "count": 3,
"file": "log.txt"
} }


### positional args ### positional args
All parsed arguments that don't fit the `-a` or `--atomic` format and aren't attached to an option are positional and can be matched on via the `position`: All parsed arguments that don't fit the `-a` or `--atomic` format and aren't attached to an option are positional and can be matched on via the `position`:


var options = require("nomnom") var options = nomnom.opts({
.opts({ filename: {
filename: { position: 0,
position: 0, help: 'file to edit'
help: 'file to edit' }
} }).parseArgs();
})
.parseArgs();


console.log(options.filename); console.log(options.filename);

### callbacks
You can provide a callback that will be executed as soon as the arg is encountered. If the callback returns a string it will print the string and exit:

This comment has been minimized.

Copy link
@jsocol

jsocol Apr 18, 2011

Contributor

With this change this is a complete superset and improvement of the functionality in the node optparse port.


var opts = {
version: {
string: '--version'
callback: function() {
return "version 1.2.4";
}
},
date: {
string: '-d YYYY-MM-DD, --date=YYYY-MM-DD',
callback: function(date) {
if(!(/^\d{4}\-\d\d\-\d\d$/).test(date))
return "date must be in format yyyy-mm-dd";
}
}
}

var options = nomnom.opts(opts).parseArgs();


### printing usage ### printing usage
Nomnom prints out a usage message if `--help` or `-h` is an argument. You can override the usage string with `usage`: Nomnom prints out a usage message if `--help` or `-h` is an argument. You can override the usage string with `usage`:
Expand Down
42 changes: 24 additions & 18 deletions lib/nomnom.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ function ArgParser() {
}); });
return match; return match;
}; };


function optName(arg) { function setOption(options, arg, value) {
return opt(arg).name || arg; var option = opt(arg);
if(option.callback) {
var message = option.callback(value);
if(typeof message == "string"){
parser.print(message);
}
}
options[option.name || arg] = value;
}; };


var parser = { var parser = {
Expand Down Expand Up @@ -91,7 +98,7 @@ function ArgParser() {
printHelp = true; printHelp = true;
argv = parserOpts.argv; argv = parserOpts.argv;
} }
var print = parser.print || function(str) { parser.print = parser.print || function(str) {
require("sys").puts(str); require("sys").puts(str);
process.exit(0); process.exit(0);
}; };
Expand All @@ -118,7 +125,7 @@ function ArgParser() {
// command specified e.g. 'git add -p' // command specified e.g. 'git add -p'
var command = parser.commands[commandName]; var command = parser.commands[commandName];
if(!command) if(!command)
print(parser.script + ": no such command '" + commandName + "'"); parser.print(parser.script + ": no such command '" + commandName + "'");
parser.specs = _(command.specs).extend(parser.specs); parser.specs = _(command.specs).extend(parser.specs);
parser.script += " " + command.name; parser.script += " " + command.name;
if(command.help) if(command.help)
Expand All @@ -140,18 +147,17 @@ function ArgParser() {
/* parse the args */ /* parse the args */
if(printHelp && (argv.indexOf("--help") != -1 if(printHelp && (argv.indexOf("--help") != -1
|| argv.indexOf("-h") != -1)) || argv.indexOf("-h") != -1))
print(parser.getUsage()); parser.print(parser.getUsage());

var options = {}; var options = {};
parser.specs.forEach(function(opt) { parser.specs.forEach(function(opt) {
options[opt.name] = opt.default; options[opt.name] = opt.default;
}, parser); });

args = argv.concat([""]).map(function(arg) { args = argv.concat([""]).map(function(arg) {
return Arg(arg); return Arg(arg);
}); });
var positionals = []; var positionals = [];
var that = parser;


args.reduce(function(arg, val) { args.reduce(function(arg, val) {
/* word */ /* word */
Expand All @@ -162,13 +168,13 @@ function ArgParser() {
else if(arg.chars) { else if(arg.chars) {
/* -cfv */ /* -cfv */
(arg.chars).forEach(function(ch) { (arg.chars).forEach(function(ch) {
options[optName(ch)] = true; setOption(options, ch, true);
}, that); });
/* -c 3 */ /* -c 3 */
if(val.isValue) { if(val.isValue) {
var expectsValue = opt(arg.lastChar).expectsValue(); var expectsValue = opt(arg.lastChar).expectsValue();
if(expectsValue) { if(expectsValue) {
options[optName(arg.lastChar)] = val.value; setOption(options, arg.lastChar, val.value);
return Arg(""); // skip next turn - swallow arg return Arg(""); // skip next turn - swallow arg
} }
} }
Expand All @@ -179,20 +185,20 @@ function ArgParser() {
/* --debug */ /* --debug */
if(value == undefined) if(value == undefined)
value = true; value = true;
options[optName(arg.lg)] = value; setOption(options, arg.lg, value);
} }
return val; return val;
}); });


positionals.forEach(function(pos, index) { positionals.forEach(function(pos, index) {
options[optName(index)] = pos; setOption(options, index, pos);
}, parser); });


// exit if required arg isn't present // exit if required arg isn't present
parser.specs.forEach(function(opt) { parser.specs.forEach(function(opt) {
if(opt.required && !options[opt.name]) if(opt.required && !options[opt.name])
print(opt.name + " argument is required"); parser.print(opt.name + " argument is required");
}, parser); });


if(command && command.callback) if(command && command.callback)
command.callback(options); command.callback(options);
Expand Down
32 changes: 32 additions & 0 deletions test/callback.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,32 @@
var nomnom = require("../lib/nomnom"),
assert = require('assert');

var opts = {
version: {
string: '--version',
callback: function() {
assert.ok(true, "called version callback");
}
},
date: {
string: '-d YYYY-MM-DD, --date=YYYY-MM-DD',
callback: function(date) {
assert.equal(date, "2010-02-03", "date should match value")
}
}
}

var options = nomnom().opts(opts).parseArgs(["--version", "--date=2010-02-03"]);

/* // exits process
nomnom().opts({
version: {
string: '--version',
callback: function() {
return "called version callback";
}
}
}).parseArgs(["--version"]);
assert.ok(false, "should have exited when --version specified");
*/

0 comments on commit 8293e17

Please sign in to comment.