From d50822ac10e1b05f2e9643671ca131ac251b6732 Mon Sep 17 00:00:00 2001 From: "Benjamin E. Coe" Date: Sun, 9 Feb 2020 19:30:47 -0800 Subject: [PATCH] feat: introduce nargs-eats-options config option (#246) --- README.md | 7 +++++++ index.js | 22 ++++++++++++++-------- test/yargs-parser.js | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b8596727..1678664d 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,13 @@ node example.js -x 1 2 -x 3 4 { _: [], x: [[1, 2], [3, 4]] } ``` +### nargs eats options + +* default: `false` +* key: `nargs-eats-options` + +Should nargs consume dash options as well as positional arguments. + ### negation prefix * default: `no-` diff --git a/index.js b/index.js index f7a3d378..0c5ad4e9 100644 --- a/index.js +++ b/index.js @@ -27,7 +27,8 @@ function parse (args, opts) { 'halt-at-non-option': false, 'strip-aliased': false, 'strip-dashed': false, - 'unknown-options-as-args': false + 'unknown-options-as-args': false, + 'nargs-eats-options': false }, opts.configuration) const defaults = Object.assign(Object.create(null), opts.default) const configObjects = opts.configObjects || [] @@ -366,16 +367,21 @@ function parse (args, opts) { return i } - // nargs will not consume flag arguments, e.g., -abc, --foo, - // and terminates when one is observed. let available = 0 - for (ii = i + 1; ii < args.length; ii++) { - if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) available++ - else break + if (configuration['nargs-eats-options']) { + // classic behavior, yargs eats positional and dash arguments. + if (args.length - (i + 1) < toEat) error = Error(__('Not enough arguments following: %s', key)) + available = toEat + } else { + // nargs will not consume flag arguments, e.g., -abc, --foo, + // and terminates when one is observed. + for (ii = i + 1; ii < args.length; ii++) { + if (!args[ii].match(/^-[^0-9]/) || args[ii].match(negative) || isUnknownOptionAsArg(args[ii])) available++ + else break + } + if (available < toEat) error = Error(__('Not enough arguments following: %s', key)) } - if (available < toEat) error = Error(__('Not enough arguments following: %s', key)) - const consumed = Math.min(available, toEat) for (ii = i + 1; ii < (consumed + i + 1); ii++) { setArg(key, args[ii]) diff --git a/test/yargs-parser.js b/test/yargs-parser.js index 60068165..0fd4c6f0 100644 --- a/test/yargs-parser.js +++ b/test/yargs-parser.js @@ -1903,6 +1903,21 @@ describe('yargs-parser', function () { result.error.message.should.equal('Not enough arguments following: foo') }) + // See: https://github.com/yargs/yargs-parser/issues/232 + it('should treat flag arguments as satisfying narg requirements, if nargs-eats-options=true', function () { + var result = parser.detailed(['--foo', '--bar', '99', '--batman', 'robin'], { + narg: { + foo: 2 + }, + configuration: { + 'nargs-eats-options': true + } + }) + + result.argv.foo.should.eql(['--bar', 99]) + result.argv.batman.should.eql('robin') + }) + it('should not consume more than configured nargs', function () { var result = parser(['--foo', 'a', 'b'], { narg: {