Skip to content

Commit ef771ca

Browse files
hendereabcoe
authored andcommitted
feat!: rework collect-unknown-options into unknown-options-as-args, providing more comprehensive functionality
1 parent ac11361 commit ef771ca

File tree

3 files changed

+74
-37
lines changed

3 files changed

+74
-37
lines changed

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -386,26 +386,26 @@ node example.js --test-field 1
386386
{ _: [], testField: 1 }
387387
```
388388
389-
### collect unknown options
389+
### unknown options as args
390390
391391
* default: `false`
392-
* key: `collect-unknown-options`
392+
* key: `unknown-options-as-args`
393393
394-
Should unknown options be collected into `_`? An unknown option is one that is not
394+
Should unknown options be treated like regular arguments? An unknown option is one that is not
395395
configured in `opts`.
396396
397397
_If disabled_
398398
399399
```sh
400-
node example.js --unknown-option --known-option 2
401-
{ _: [], unknownOption: true, knownOption: 2 }
400+
node example.js --unknown-option --known-option 2 --string-option --unknown-option2
401+
{ _: [], unknownOption: true, knownOption: 2, stringOption: '', unknownOption2: true }
402402
```
403403
404404
_If enabled_
405405
406406
```sh
407-
node example.js --unknown-option --known-option 2
408-
{ _: ['--unknown-option'], knownOption: 2 }
407+
node example.js --unknown-option --known-option 2 --string-option --unknown-option2
408+
{ _: ['--unknown-option'], knownOption: 2, stringOption: '--unknown-option2' }
409409
```
410410
411411
## Special Thanks

index.js

+13-16
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function parse (args, opts) {
2727
'halt-at-non-option': false,
2828
'strip-aliased': false,
2929
'strip-dashed': false,
30-
'collect-unknown-options': false
30+
'unknown-options-as-args': false
3131
}, opts.configuration)
3232
var defaults = opts.default || {}
3333
var configObjects = opts.configObjects || []
@@ -143,7 +143,7 @@ function parse (args, opts) {
143143
var next
144144
var value
145145

146-
if (configuration['collect-unknown-options'] && isUnknownOption(arg)) {
146+
if (isUnknownOptionAsArg(arg)) {
147147
argv._.push(arg)
148148
// -- separated by =
149149
} else if (arg.match(/^--.+=/) || (
@@ -361,7 +361,7 @@ function parse (args, opts) {
361361
// and terminates when one is observed.
362362
var available = 0
363363
for (ii = i + 1; ii < args.length; ii++) {
364-
if (!args[ii].match(/^-[^0-9]/)) available++
364+
if (!args[ii].match(/^-[^0-9]/) || isUnknownOptionAsArg(args[ii])) available++
365365
else break
366366
}
367367

@@ -384,7 +384,7 @@ function parse (args, opts) {
384384

385385
if (checkAllAliases(key, flags.bools) && !(/^(true|false)$/.test(next))) {
386386
argsToSet.push(true)
387-
} else if (isUndefined(next) || (/^-/.test(next) && !negative.test(next))) {
387+
} else if (isUndefined(next) || (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next))) {
388388
// for keys without value ==> argsToSet remains an empty []
389389
// set user default value, if available
390390
if (defaults.hasOwnProperty(key)) {
@@ -393,7 +393,7 @@ function parse (args, opts) {
393393
} else {
394394
for (var ii = i + 1; ii < args.length; ii++) {
395395
next = args[ii]
396-
if (/^-/.test(next) && !negative.test(next)) break
396+
if (/^-/.test(next) && !negative.test(next) && !isUnknownOptionAsArg(next)) break
397397
i = ii
398398
argsToSet.push(processValue(key, next))
399399
}
@@ -761,27 +761,20 @@ function parse (args, opts) {
761761
}
762762

763763
function hasAnyFlag (key) {
764-
var isSet = false
765764
// XXX Switch to [].concat(...Object.values(flags)) once node.js 6 is dropped
766765
var toCheck = [].concat(...Object.keys(flags).map(k => flags[k]))
767766

768-
toCheck.forEach(function (flag) {
769-
if (flag[key]) isSet = flag[key]
767+
return toCheck.some(function (flag) {
768+
return flag[key]
770769
})
771-
772-
return isSet
773770
}
774771

775772
function hasFlagsMatching (arg, ...patterns) {
776-
var hasFlag = false
777773
var toCheck = [].concat(...patterns)
778-
toCheck.forEach(function (pattern) {
774+
return toCheck.some(function (pattern) {
779775
var match = arg.match(pattern)
780-
if (match && hasAnyFlag(match[1])) {
781-
hasFlag = true
782-
}
776+
return match && hasAnyFlag(match[1])
783777
})
784-
return hasFlag
785778
}
786779

787780
// based on a simplified version of the short flag group parsing logic
@@ -809,6 +802,10 @@ function parse (args, opts) {
809802
return hasAllFlags
810803
}
811804

805+
function isUnknownOptionAsArg (arg) {
806+
return configuration['unknown-options-as-args'] && isUnknownOption(arg)
807+
}
808+
812809
function isUnknownOption (arg) {
813810
// ignore negative numbers
814811
if (arg.match(negative)) { return false }

test/yargs-parser.js

+54-14
Original file line numberDiff line numberDiff line change
@@ -2690,12 +2690,12 @@ describe('yargs-parser', function () {
26902690
})
26912691
})
26922692

2693-
describe('collect-unknown-options = true', function () {
2693+
describe('unknown-options-as-args = true', function () {
26942694
it('should ignore unknown options in long format separated by =', function () {
26952695
const argv = parser('--known-arg=1 --unknown-arg=2', {
26962696
number: ['known-arg'],
26972697
configuration: {
2698-
'collect-unknown-options': true
2698+
'unknown-options-as-args': true
26992699
}
27002700
})
27012701
argv.should.deep.equal({
@@ -2708,7 +2708,7 @@ describe('yargs-parser', function () {
27082708
const argv = parser('--no-known-arg --no-unknown-arg', {
27092709
boolean: ['known-arg'],
27102710
configuration: {
2711-
'collect-unknown-options': true
2711+
'unknown-options-as-args': true
27122712
}
27132713
})
27142714
argv.should.deep.equal({
@@ -2721,7 +2721,7 @@ describe('yargs-parser', function () {
27212721
const argv = parser('--known-arg a --unknown-arg b', {
27222722
string: ['known-arg'],
27232723
configuration: {
2724-
'collect-unknown-options': true
2724+
'unknown-options-as-args': true
27252725
}
27262726
})
27272727
argv.should.deep.equal({
@@ -2734,7 +2734,7 @@ describe('yargs-parser', function () {
27342734
const argv = parser('-k.arg=a -u.arg=b', {
27352735
string: ['k.arg'],
27362736
configuration: {
2737-
'collect-unknown-options': true
2737+
'unknown-options-as-args': true
27382738
}
27392739
})
27402740
argv.should.deep.equal({
@@ -2748,7 +2748,7 @@ describe('yargs-parser', function () {
27482748
const argv = parser('-k.arg 1 -u.arg 2', {
27492749
number: ['k.arg'],
27502750
configuration: {
2751-
'collect-unknown-options': true
2751+
'unknown-options-as-args': true
27522752
}
27532753
})
27542754
argv.should.deep.equal({
@@ -2762,7 +2762,7 @@ describe('yargs-parser', function () {
27622762
const argv = parser('-k=a -u=b', {
27632763
string: ['k'],
27642764
configuration: {
2765-
'collect-unknown-options': true
2765+
'unknown-options-as-args': true
27662766
}
27672767
})
27682768
argv.should.deep.equal({
@@ -2774,7 +2774,7 @@ describe('yargs-parser', function () {
27742774
const argv = parser('-k- -u-', {
27752775
string: ['k'],
27762776
configuration: {
2777-
'collect-unknown-options': true
2777+
'unknown-options-as-args': true
27782778
}
27792779
})
27802780
argv.should.deep.equal({
@@ -2786,19 +2786,59 @@ describe('yargs-parser', function () {
27862786
const argv = parser('-k 1 -u 2', {
27872787
number: ['k'],
27882788
configuration: {
2789-
'collect-unknown-options': true
2789+
'unknown-options-as-args': true
27902790
}
27912791
})
27922792
argv.should.deep.equal({
27932793
_: ['-u', '2'],
27942794
'k': 1
27952795
})
27962796
})
2797+
it('should allow an unknown arg to be used as the value of another flag in short form', function () {
2798+
const argv = parser('-k -u', {
2799+
string: ['k'],
2800+
narg: { 'k': 1 },
2801+
configuration: {
2802+
'unknown-options-as-args': true
2803+
}
2804+
})
2805+
argv.should.deep.equal({
2806+
_: [],
2807+
'k': '-u'
2808+
})
2809+
})
2810+
it('should allow an unknown arg to be used as the value of another flag in long form', function () {
2811+
const argv = parser('--known-arg --unknown-arg', {
2812+
string: ['known-arg'],
2813+
narg: { 'known-arg': 1 },
2814+
configuration: {
2815+
'unknown-options-as-args': true
2816+
}
2817+
})
2818+
argv.should.deep.equal({
2819+
_: [],
2820+
'knownArg': '--unknown-arg',
2821+
'known-arg': '--unknown-arg'
2822+
})
2823+
})
2824+
it('should allow an unknown arg to be used as the value of another flag in array form', function () {
2825+
const argv = parser('--known-arg --unknown-arg1 --unknown-arg2', {
2826+
array: ['known-arg'],
2827+
configuration: {
2828+
'unknown-options-as-args': true
2829+
}
2830+
})
2831+
argv.should.deep.equal({
2832+
_: [],
2833+
'knownArg': ['--unknown-arg1', '--unknown-arg2'],
2834+
'known-arg': ['--unknown-arg1', '--unknown-arg2']
2835+
})
2836+
})
27972837
it('should ignore unknown options in short format followed by a number', function () {
27982838
const argv = parser('-k1 -u2', {
27992839
number: ['k'],
28002840
configuration: {
2801-
'collect-unknown-options': true
2841+
'unknown-options-as-args': true
28022842
}
28032843
})
28042844
argv.should.deep.equal({
@@ -2810,7 +2850,7 @@ describe('yargs-parser', function () {
28102850
const argv = parser('-k/1/ -u/2/', {
28112851
string: ['k'],
28122852
configuration: {
2813-
'collect-unknown-options': true
2853+
'unknown-options-as-args': true
28142854
}
28152855
})
28162856
argv.should.deep.equal({
@@ -2822,7 +2862,7 @@ describe('yargs-parser', function () {
28222862
const argv = parser('-kuv', {
28232863
boolean: ['k', 'v'],
28242864
configuration: {
2825-
'collect-unknown-options': true
2865+
'unknown-options-as-args': true
28262866
}
28272867
})
28282868
argv.should.deep.equal({
@@ -2833,7 +2873,7 @@ describe('yargs-parser', function () {
28332873
const argv = parser('-kv', {
28342874
boolean: ['k', 'v'],
28352875
configuration: {
2836-
'collect-unknown-options': true
2876+
'unknown-options-as-args': true
28372877
}
28382878
})
28392879
argv.should.deep.equal({
@@ -2846,7 +2886,7 @@ describe('yargs-parser', function () {
28462886
const argv = parser('-k -33', {
28472887
boolean: ['k'],
28482888
configuration: {
2849-
'collect-unknown-options': true
2889+
'unknown-options-as-args': true
28502890
}
28512891
})
28522892
argv.should.deep.equal({

0 commit comments

Comments
 (0)