Skip to content

Commit 41d3f81

Browse files
authored
fix(array, nargs): support -o=--value and --option=--value format (#262)
1 parent b96b989 commit 41d3f81

File tree

2 files changed

+90
-19
lines changed

2 files changed

+90
-19
lines changed

index.js

+29-19
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,10 @@ function parse (args, opts) {
167167

168168
// arrays format = '--f=a b c'
169169
if (checkAllAliases(m[1], flags.arrays)) {
170-
args.splice(i + 1, 0, m[2])
171-
i = eatArray(i, m[1], args)
172-
} else if (checkAllAliases(m[1], flags.nargs)) {
170+
i = eatArray(i, m[1], args, m[2])
171+
} else if (checkAllAliases(m[1], flags.nargs) !== false) {
173172
// nargs format = '--f=monkey washing cat'
174-
args.splice(i + 1, 0, m[2])
175-
i = eatNargs(i, m[1], args)
173+
i = eatNargs(i, m[1], args, m[2])
176174
} else {
177175
setArg(m[1], m[2])
178176
}
@@ -241,12 +239,10 @@ function parse (args, opts) {
241239

242240
if (checkAllAliases(key, flags.arrays)) {
243241
// array format = '-f=a b c'
244-
args.splice(i + 1, 0, value)
245-
i = eatArray(i, key, args)
246-
} else if (checkAllAliases(key, flags.nargs)) {
242+
i = eatArray(i, key, args, value)
243+
} else if (checkAllAliases(key, flags.nargs) !== false) {
247244
// nargs format = '-f=monkey washing cat'
248-
args.splice(i + 1, 0, value)
249-
i = eatNargs(i, key, args)
245+
i = eatNargs(i, key, args, value)
250246
} else {
251247
setArg(key, value)
252248
}
@@ -364,22 +360,27 @@ function parse (args, opts) {
364360

365361
// how many arguments should we consume, based
366362
// on the nargs option?
367-
function eatNargs (i, key, args) {
363+
function eatNargs (i, key, args, argAfterEqualSign) {
368364
let ii
369365
let toEat = checkAllAliases(key, flags.nargs)
370366
// NaN has a special meaning for the array type, indicating that one or
371367
// more values are expected.
372368
toEat = isNaN(toEat) ? 1 : toEat
373369

374370
if (toEat === 0) {
371+
if (!isUndefined(argAfterEqualSign)) {
372+
error = Error(__('Argument unexpected for: %s', key))
373+
}
375374
setArg(key, defaultValue(key))
376375
return i
377376
}
378377

379-
let available = 0
378+
let available = isUndefined(argAfterEqualSign) ? 0 : 1
380379
if (configuration['nargs-eats-options']) {
381380
// classic behavior, yargs eats positional and dash arguments.
382-
if (args.length - (i + 1) < toEat) error = Error(__('Not enough arguments following: %s', key))
381+
if (args.length - (i + 1) + available < toEat) {
382+
error = Error(__('Not enough arguments following: %s', key))
383+
}
383384
available = toEat
384385
} else {
385386
// nargs will not consume flag arguments, e.g., -abc, --foo,
@@ -391,7 +392,11 @@ function parse (args, opts) {
391392
if (available < toEat) error = Error(__('Not enough arguments following: %s', key))
392393
}
393394

394-
const consumed = Math.min(available, toEat)
395+
let consumed = Math.min(available, toEat)
396+
if (!isUndefined(argAfterEqualSign) && consumed > 0) {
397+
setArg(key, argAfterEqualSign)
398+
consumed--
399+
}
395400
for (ii = i + 1; ii < (consumed + i + 1); ii++) {
396401
setArg(key, args[ii])
397402
}
@@ -402,29 +407,34 @@ function parse (args, opts) {
402407
// if an option is an array, eat all non-hyphenated arguments
403408
// following it... YUM!
404409
// e.g., --foo apple banana cat becomes ["apple", "banana", "cat"]
405-
function eatArray (i, key, args) {
410+
function eatArray (i, key, args, argAfterEqualSign) {
406411
let argsToSet = []
407-
let next = args[i + 1]
412+
let next = argAfterEqualSign || args[i + 1]
408413
// If both array and nargs are configured, enforce the nargs count:
409414
const nargsCount = checkAllAliases(key, flags.nargs)
410415

411416
if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) {
412417
argsToSet.push(true)
413-
} else if (isUndefined(next) || (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) {
418+
} else if (isUndefined(next) ||
419+
(isUndefined(argAfterEqualSign) && /^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) {
414420
// for keys without value ==> argsToSet remains an empty []
415421
// set user default value, if available
416422
if (defaults[key] !== undefined) {
417423
const defVal = defaults[key]
418424
argsToSet = Array.isArray(defVal) ? defVal : [defVal]
419425
}
420426
} else {
427+
// value in --option=value is eaten as is
428+
if (!isUndefined(argAfterEqualSign)) {
429+
argsToSet.push(processValue(key, argAfterEqualSign))
430+
}
421431
for (let ii = i + 1; ii < args.length; ii++) {
432+
if ((!configuration['greedy-arrays'] && argsToSet.length > 0) ||
433+
(nargsCount && argsToSet.length >= nargsCount)) break
422434
next = args[ii]
423435
if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) break
424436
i = ii
425437
argsToSet.push(processValue(key, next))
426-
if (!configuration['greedy-arrays'] ||
427-
(nargsCount && argsToSet.length >= nargsCount)) break
428438
}
429439
}
430440

test/yargs-parser.js

+61
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,20 @@ describe('yargs-parser', function () {
17481748
result['1'][1].should.equal('b')
17491749
})
17501750

1751+
it('should support array for -f= and --bar= format when the value is dashed', function () {
1752+
var result = parser(['-f=--dog', 'cat', '--bar=--red', 'green'], {
1753+
array: ['f', 'bar']
1754+
})
1755+
1756+
Array.isArray(result.f).should.equal(true)
1757+
result.f[0].should.equal('--dog')
1758+
result.f[1].should.equal('cat')
1759+
1760+
Array.isArray(result.bar).should.equal(true)
1761+
result.bar[0].should.equal('--red')
1762+
result.bar[1].should.equal('green')
1763+
})
1764+
17511765
it('should create an array when passing an argument twice with same value', function () {
17521766
var result = parser(['-x', 'val1', '-x', 'val1'])
17531767
result.should.have.property('x').that.is.an('array').and.to.deep.equal(['val1', 'val1'])
@@ -1869,6 +1883,24 @@ describe('yargs-parser', function () {
18691883
result.foo[1].should.equal('bar')
18701884
})
18711885

1886+
it('should raise an exception if -f== format is used for a key with no expected argument', function () {
1887+
var argv = parser.detailed('-f=apple', {
1888+
narg: {
1889+
f: 0
1890+
}
1891+
})
1892+
argv.error.message.should.equal('Argument unexpected for: f')
1893+
})
1894+
1895+
it('should raise an exception if --bar== format is used for a key with no expected argument', function () {
1896+
var argv = parser.detailed('--bar=apple', {
1897+
narg: {
1898+
bar: 0
1899+
}
1900+
})
1901+
argv.error.message.should.equal('Argument unexpected for: bar')
1902+
})
1903+
18721904
it('should raise an exception if there are not enough arguments following key', function () {
18731905
var argv = parser.detailed('--foo apple', {
18741906
narg: {
@@ -1921,6 +1953,23 @@ describe('yargs-parser', function () {
19211953
result._[1].should.equal('cat')
19221954
})
19231955

1956+
it('should support nargs for -f= and --bar= format arguments with dashed values', function () {
1957+
var result = parser(['-f=--apple', 'bar', 'blerg', '--bar=-monkey', 'washing', 'cat'], {
1958+
narg: {
1959+
f: 2,
1960+
bar: 2
1961+
}
1962+
})
1963+
1964+
result.f[0].should.equal('--apple')
1965+
result.f[1].should.equal('bar')
1966+
result._[0].should.equal('blerg')
1967+
1968+
result.bar[0].should.equal('-monkey')
1969+
result.bar[1].should.equal('washing')
1970+
result._[1].should.equal('cat')
1971+
})
1972+
19241973
it('should not modify the input args if an = was used', function () {
19251974
var expected = ['-f=apple', 'bar', 'blerg', '--bar=monkey', 'washing', 'cat']
19261975
var args = expected.slice()
@@ -3680,6 +3729,18 @@ describe('yargs-parser', function () {
36803729
parse.error.message.should.equal('Not enough arguments following: a')
36813730
})
36823731

3732+
it('returns an error if not enough positionals were provided for nargs even with nargs-eats-options', () => {
3733+
var parse = parser.detailed(['-a', '33', '--cat'], {
3734+
narg: {
3735+
a: 3
3736+
},
3737+
configuration: {
3738+
'nargs-eats-options': true
3739+
}
3740+
})
3741+
parse.error.message.should.equal('Not enough arguments following: a')
3742+
})
3743+
36833744
it('does not raise error if no arguments are provided for boolean option', () => {
36843745
var parse = parser.detailed(['-a'], {
36853746
array: 'a',

0 commit comments

Comments
 (0)