fixing optparse to behave nicely in the presence of hashbangs -- stop parsing after the first non-option argument, and pass the rest along -- and adding an OptionParser test.

This commit is contained in:
Jeremy Ashkenas 2010-07-11 09:57:42 -04:00
parent 3d6cdfa636
commit 2a7a26482a
5 changed files with 44 additions and 16 deletions

View File

@ -191,10 +191,10 @@
parseOptions = function() {
var o;
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
o = (options = optionParser.parse(process.argv));
o = (options = optionParser.parse(process.argv.slice(2, process.argv.length)));
options.run = !(o.compile || o.print || o.lint);
options.print = !!(o.print || (o.eval || o.stdio && o.compile));
sources = options.arguments.slice(2, options.arguments.length);
sources = options.arguments;
return sources;
};
compileOptions = function(source) {

View File

@ -7,19 +7,21 @@
return this;
};
OptionParser.prototype.parse = function(args) {
var _a, _b, _c, arg, isOption, matchedRule, options, rule;
var _a, _b, _c, _d, _e, arg, i, isOption, matchedRule, options, rule;
options = {
arguments: []
};
args = normalizeArguments(args);
while ((arg = args.shift())) {
_a = args;
for (i = 0, _b = _a.length; i < _b; i++) {
arg = _a[i];
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
matchedRule = false;
_b = this.rules;
for (_a = 0, _c = _b.length; _a < _c; _a++) {
rule = _b[_a];
_d = this.rules;
for (_c = 0, _e = _d.length; _c < _e; _c++) {
rule = _d[_c];
if (rule.shortFlag === arg || rule.longFlag === arg) {
options[rule.name] = rule.hasArgument ? args.shift() : true;
options[rule.name] = rule.hasArgument ? args[i + 1] : true;
matchedRule = true;
break;
}
@ -27,8 +29,9 @@
if (isOption && !matchedRule) {
throw new Error("unrecognized option: " + arg);
}
if (!(isOption)) {
options.arguments.push(arg);
if (!isOption) {
options.arguments = args.slice(i, args.length);
break;
}
}
return options;

View File

@ -154,11 +154,11 @@ printTokens: (tokens) ->
# Use the [OptionParser module](optparse.html) to extract all options from
# `process.argv` that are specified in `SWITCHES`.
parseOptions: ->
optionParser: new optparse.OptionParser SWITCHES, BANNER
o: options: optionParser.parse(process.argv)
optionParser: new optparse.OptionParser SWITCHES, BANNER
o: options: optionParser.parse(process.argv[2...process.argv.length])
options.run: not (o.compile or o.print or o.lint)
options.print: !! (o.print or (o.eval or o.stdio and o.compile))
sources: options.arguments[2...options.arguments.length]
sources: options.arguments
# The compile-time options to pass to the CoffeeScript compiler.
compileOptions: (source) ->

View File

@ -3,6 +3,9 @@
#
# parser: new OptionParser switches, helpBanner
# options: parser.parse process.argv
#
# The first non-option is considered to be the start of the file (and file
# option) list, and all subsequent arguments are left unparsed.
exports.OptionParser: class OptionParser
# Initialize with a list of valid options, in the form:
@ -22,16 +25,18 @@ exports.OptionParser: class OptionParser
parse: (args) ->
options: {arguments: []}
args: normalizeArguments args
while (arg: args.shift())
for arg, i in args
isOption: !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
matchedRule: no
for rule in @rules
if rule.shortFlag is arg or rule.longFlag is arg
options[rule.name]: if rule.hasArgument then args.shift() else true
options[rule.name]: if rule.hasArgument then args[i + 1] else true
matchedRule: yes
break
throw new Error "unrecognized option: $arg" if isOption and not matchedRule
options.arguments.push arg unless isOption
if not isOption
options.arguments: args[i...args.length]
break
options
# Return the help text for this **OptionParser**, listing and describing all

View File

@ -0,0 +1,20 @@
# Ensure that the OptionParser handles arguments correctly.
{OptionParser}: require './../lib/optparse'
opt: new OptionParser [
['-r', '--required [DIR]', 'desc required']
['-o', '--optional', 'desc optional']
]
result: opt.parse ['one', 'two', 'three', '-r', 'dir']
ok result.arguments.length is 5
ok result.arguments[3] is '-r'
result: opt.parse ['--optional', '-r', 'folder', 'one', 'two']
ok result.optional is true
ok result.required is 'folder'
ok result.arguments.join(' ') is 'folder one two'