mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
OptionParser and related tests needed a cleanup
The object returned from OptionParser::parse no longer has a `literals` property. It was pretty arbitrary, anyway.
This commit is contained in:
parent
eb5c4057a1
commit
c0dac45fe1
5 changed files with 80 additions and 68 deletions
|
@ -43,7 +43,7 @@
|
||||||
optionParser = null;
|
optionParser = null;
|
||||||
|
|
||||||
exports.run = function() {
|
exports.run = function() {
|
||||||
var source, _i, _len, _results;
|
var literals, source, _i, _len, _results;
|
||||||
parseOptions();
|
parseOptions();
|
||||||
if (opts.nodejs) return forkNode();
|
if (opts.nodejs) return forkNode();
|
||||||
if (opts.help) return usage();
|
if (opts.help) return usage();
|
||||||
|
@ -56,8 +56,8 @@
|
||||||
if (opts.stdio) return compileStdio();
|
if (opts.stdio) return compileStdio();
|
||||||
if (opts["eval"]) return compileScript(null, sources[0]);
|
if (opts["eval"]) return compileScript(null, sources[0]);
|
||||||
if (!sources.length) return require('./repl');
|
if (!sources.length) return require('./repl');
|
||||||
if (opts.run) opts.literals = sources.splice(1).concat(opts.literals);
|
literals = opts.run ? sources.splice(1) : [];
|
||||||
process.argv = process.argv.slice(0, 2).concat(opts.literals);
|
process.argv = process.argv.slice(0, 2).concat(literals);
|
||||||
process.argv[0] = 'coffee';
|
process.argv[0] = 'coffee';
|
||||||
process.execPath = require.main.filename;
|
process.execPath = require.main.filename;
|
||||||
_results = [];
|
_results = [];
|
||||||
|
|
|
@ -12,10 +12,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionParser.prototype.parse = function(args) {
|
OptionParser.prototype.parse = function(args) {
|
||||||
var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, skippingArgument, value, _i, _j, _len, _len2, _ref;
|
var arg, i, isOption, matchedRule, options, originalArgs, pos, rule, seenNonOptionArg, skippingArgument, value, _i, _j, _len, _len2, _ref;
|
||||||
options = {
|
options = {
|
||||||
"arguments": [],
|
"arguments": []
|
||||||
literals: []
|
|
||||||
};
|
};
|
||||||
skippingArgument = false;
|
skippingArgument = false;
|
||||||
originalArgs = args;
|
originalArgs = args;
|
||||||
|
@ -28,17 +27,22 @@
|
||||||
}
|
}
|
||||||
if (arg === '--') {
|
if (arg === '--') {
|
||||||
pos = originalArgs.indexOf('--');
|
pos = originalArgs.indexOf('--');
|
||||||
options["arguments"] = [originalArgs[1 + pos]];
|
options["arguments"] = options["arguments"].concat(originalArgs.slice(pos + 1));
|
||||||
options.literals = originalArgs.slice(2 + pos);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
|
isOption = !!(arg.match(LONG_FLAG) || arg.match(SHORT_FLAG));
|
||||||
|
seenNonOptionArg = options["arguments"].length > 0;
|
||||||
|
if (!seenNonOptionArg) {
|
||||||
matchedRule = false;
|
matchedRule = false;
|
||||||
_ref = this.rules;
|
_ref = this.rules;
|
||||||
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||||
rule = _ref[_j];
|
rule = _ref[_j];
|
||||||
if (rule.shortFlag === arg || rule.longFlag === arg) {
|
if (rule.shortFlag === arg || rule.longFlag === arg) {
|
||||||
value = rule.hasArgument ? (skippingArgument = true, args[i + 1]) : true;
|
value = true;
|
||||||
|
if (rule.hasArgument) {
|
||||||
|
skippingArgument = true;
|
||||||
|
value = args[i + 1];
|
||||||
|
}
|
||||||
options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
|
options[rule.name] = rule.isList ? (options[rule.name] || []).concat(value) : value;
|
||||||
matchedRule = true;
|
matchedRule = true;
|
||||||
break;
|
break;
|
||||||
|
@ -47,10 +51,8 @@
|
||||||
if (isOption && !matchedRule) {
|
if (isOption && !matchedRule) {
|
||||||
throw new Error("unrecognized option: " + arg);
|
throw new Error("unrecognized option: " + arg);
|
||||||
}
|
}
|
||||||
if (!isOption) {
|
|
||||||
options["arguments"] = originalArgs.slice(originalArgs.indexOf(arg));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (seenNonOptionArg || !isOption) options["arguments"].push(arg);
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
@ -74,9 +76,9 @@
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
LONG_FLAG = /^(--\w[\w\-]+)/;
|
LONG_FLAG = /^(--\w[\w\-]*)/;
|
||||||
|
|
||||||
SHORT_FLAG = /^(-\w)/;
|
SHORT_FLAG = /^(-\w)$/;
|
||||||
|
|
||||||
MULTI_FLAG = /^-(\w{2,})/;
|
MULTI_FLAG = /^-(\w{2,})/;
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,8 @@ exports.run = ->
|
||||||
return compileStdio() if opts.stdio
|
return compileStdio() if opts.stdio
|
||||||
return compileScript null, sources[0] if opts.eval
|
return compileScript null, sources[0] if opts.eval
|
||||||
return require './repl' unless sources.length
|
return require './repl' unless sources.length
|
||||||
if opts.run
|
literals = if opts.run then sources.splice 1 else []
|
||||||
opts.literals = sources.splice(1).concat opts.literals
|
process.argv = process.argv[0..1].concat literals
|
||||||
process.argv = process.argv[0..1].concat opts.literals
|
|
||||||
process.argv[0] = 'coffee'
|
process.argv[0] = 'coffee'
|
||||||
process.execPath = require.main.filename
|
process.execPath = require.main.filename
|
||||||
for source in sources
|
for source in sources
|
||||||
|
|
|
@ -17,14 +17,13 @@ exports.OptionParser = class OptionParser
|
||||||
@rules = buildRules rules
|
@rules = buildRules rules
|
||||||
|
|
||||||
# Parse the list of arguments, populating an `options` object with all of the
|
# Parse the list of arguments, populating an `options` object with all of the
|
||||||
# specified options, and return it. `options.arguments` will be an array
|
# specified options, and return it. Options after the first non-option
|
||||||
# containing the remaining non-option arguments. `options.literals` will be
|
# argument are treated as arguments. `options.arguments` will be an array
|
||||||
# an array of options that are meant to be passed through directly to the
|
# containing the remaining arguments. This is a simpler API than many option
|
||||||
# executing script. This is a simpler API than many option parsers that allow
|
# parsers that allow you to attach callback actions for every flag. Instead,
|
||||||
# you to attach callback actions for every flag. Instead, you're responsible
|
# you're responsible for interpreting the options object.
|
||||||
# for interpreting the options object.
|
|
||||||
parse: (args) ->
|
parse: (args) ->
|
||||||
options = arguments: [], literals: []
|
options = arguments: []
|
||||||
skippingArgument = no
|
skippingArgument = no
|
||||||
originalArgs = args
|
originalArgs = args
|
||||||
args = normalizeArguments args
|
args = normalizeArguments args
|
||||||
|
@ -34,25 +33,26 @@ exports.OptionParser = class OptionParser
|
||||||
continue
|
continue
|
||||||
if arg is '--'
|
if arg is '--'
|
||||||
pos = originalArgs.indexOf '--'
|
pos = originalArgs.indexOf '--'
|
||||||
options.arguments = [originalArgs[1 + pos]]
|
options.arguments = options.arguments.concat originalArgs[(pos + 1)..]
|
||||||
options.literals = originalArgs[(2 + pos)..]
|
|
||||||
break
|
break
|
||||||
isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
|
isOption = !!(arg.match(LONG_FLAG) or arg.match(SHORT_FLAG))
|
||||||
|
# the CS option parser is a little odd; options after the first
|
||||||
|
# non-option argument are treated as non-option arguments themselves
|
||||||
|
seenNonOptionArg = options.arguments.length > 0
|
||||||
|
unless seenNonOptionArg
|
||||||
matchedRule = no
|
matchedRule = no
|
||||||
for rule in @rules
|
for rule in @rules
|
||||||
if rule.shortFlag is arg or rule.longFlag is arg
|
if rule.shortFlag is arg or rule.longFlag is arg
|
||||||
value = if rule.hasArgument
|
value = true
|
||||||
|
if rule.hasArgument
|
||||||
skippingArgument = yes
|
skippingArgument = yes
|
||||||
args[i + 1]
|
value = args[i + 1]
|
||||||
else
|
|
||||||
true
|
|
||||||
options[rule.name] = if rule.isList then (options[rule.name] or []).concat value else value
|
options[rule.name] = if rule.isList then (options[rule.name] or []).concat value else value
|
||||||
matchedRule = yes
|
matchedRule = yes
|
||||||
break
|
break
|
||||||
throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule
|
throw new Error "unrecognized option: #{arg}" if isOption and not matchedRule
|
||||||
if not isOption
|
if seenNonOptionArg or not isOption
|
||||||
options.arguments = originalArgs[(originalArgs.indexOf arg)..]
|
options.arguments.push arg
|
||||||
break
|
|
||||||
options
|
options
|
||||||
|
|
||||||
# Return the help text for this **OptionParser**, listing and describing all
|
# Return the help text for this **OptionParser**, listing and describing all
|
||||||
|
@ -71,8 +71,8 @@ exports.OptionParser = class OptionParser
|
||||||
# -------
|
# -------
|
||||||
|
|
||||||
# Regex matchers for option flags.
|
# Regex matchers for option flags.
|
||||||
LONG_FLAG = /^(--\w[\w\-]+)/
|
LONG_FLAG = /^(--\w[\w\-]*)/
|
||||||
SHORT_FLAG = /^(-\w)/
|
SHORT_FLAG = /^(-\w)$/
|
||||||
MULTI_FLAG = /^-(\w{2,})/
|
MULTI_FLAG = /^-(\w{2,})/
|
||||||
OPTIONAL = /\[(\w+(\*?))\]/
|
OPTIONAL = /\[(\w+(\*?))\]/
|
||||||
|
|
||||||
|
|
|
@ -13,20 +13,31 @@ opt = new OptionParser [
|
||||||
['-l', '--list [FILES*]', 'desc list']
|
['-l', '--list [FILES*]', 'desc list']
|
||||||
]
|
]
|
||||||
|
|
||||||
result = opt.parse ['one', 'two', 'three', '-r', 'dir']
|
test "basic arguments", ->
|
||||||
|
args = ['one', 'two', 'three', '-r', 'dir']
|
||||||
eq 5, result.arguments.length
|
result = opt.parse args
|
||||||
eq '-r', result.arguments[3]
|
arrayEq args, result.arguments
|
||||||
|
eq undefined, result.required
|
||||||
|
|
||||||
|
test "boolean and parameterised options", ->
|
||||||
result = opt.parse ['--optional', '-r', 'folder', 'one', 'two']
|
result = opt.parse ['--optional', '-r', 'folder', 'one', 'two']
|
||||||
|
|
||||||
ok result.optional
|
ok result.optional
|
||||||
eq 'folder', result.required
|
eq 'folder', result.required
|
||||||
eq 'one two', result.arguments.join ' '
|
arrayEq ['one', 'two'], result.arguments
|
||||||
|
|
||||||
|
test "list options", ->
|
||||||
result = opt.parse ['-l', 'one.txt', '-l', 'two.txt', 'three']
|
result = opt.parse ['-l', 'one.txt', '-l', 'two.txt', 'three']
|
||||||
|
arrayEq ['one.txt', 'two.txt'], result.list
|
||||||
|
arrayEq ['three'], result.arguments
|
||||||
|
|
||||||
ok result.list instanceof Array
|
test "-- and interesting combinations", ->
|
||||||
ok result.list.join(' ') is 'one.txt two.txt'
|
result = opt.parse ['-o','-r','a','-r','b','-o','--','-a','b','--c','d']
|
||||||
ok result.arguments.join(' ') is 'three'
|
arrayEq ['-a', 'b', '--c', 'd'], result.arguments
|
||||||
|
ok result.optional
|
||||||
|
eq 'b', result.required
|
||||||
|
|
||||||
|
args = ['--','-o','a','-r','c','-o','--','-a','arg0','-b','arg1']
|
||||||
|
result = opt.parse args
|
||||||
|
eq undefined, result.optional
|
||||||
|
eq undefined, result.required
|
||||||
|
arrayEq args[1..], result.arguments
|
||||||
|
|
Loading…
Reference in a new issue