diff --git a/lib/commander.js b/lib/commander.js index b665194b0..01704f3e1 100644 --- a/lib/commander.js +++ b/lib/commander.js @@ -213,6 +213,20 @@ Command.prototype.action = function(fn){ self.unknownOption(parsed.unknown[0]); } + // Any remaining arguments in parsed.args were originally thought + // to be tied to options, but ended up being tied to the original + // command. + if (parsed.args.length > 0) { + parsed.args.forEach(function(arg, index) { + // For each argument that is inserted, the insertionIndex gets + // offset by one for future arguments. In order to compensate + // for this, simply add in the index of this argument in + // parsed.args to the insertionIndex, as this represents how + // many arguments have been inserted prior to this one. + args.splice(arg.insertionIndex + index - 1, 0, arg.value); + }); + } + self.args.forEach(function(arg, i){ if (arg.required && null == args[i]) { self.missingArgument(arg.name); @@ -461,7 +475,10 @@ Command.prototype.parseOptions = function(argv){ continue; } - if (literal) { + // Object arguments were parameters that were guessed + // to be tied to an option, but actually turned out to + // be arguments to the command. Pass them on as such. + if (literal || 'object' == typeof arg) { args.push(arg); continue; } @@ -475,11 +492,16 @@ Command.prototype.parseOptions = function(argv){ if (option.required) { arg = argv[++i]; if (null == arg) return this.optionMissingArgument(option); + if ('object' == typeof arg) arg = arg.value; if ('-' == arg[0]) return this.optionMissingArgument(option, arg); this.emit(option.name(), arg); // optional arg } else if (option.optional) { arg = argv[i+1]; + if ('object' == typeof arg) { + arg = arg.value; + } + if (null == arg || '-' == arg[0]) { arg = null; } else { @@ -501,7 +523,15 @@ Command.prototype.parseOptions = function(argv){ // an argument for this option, we pass it on. // If it isn't, then it'll simply be ignored if (argv[i+1] && '-' != argv[i+1][0]) { - unknownOptions.push(argv[++i]); + // This option could take no parameters, at which point + // the next argument is really for the command rather than + // the option. Thus, maintain the argument along with the + // location to insert it into the args array if necessary + // later on. + unknownOptions.push({ + value: argv[++i], + insertionIndex: args.length + }); } continue; }