diff --git a/CHANGELOG.md b/CHANGELOG.md
index e194f767..bf172df5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,16 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
+
+## [4.2.1](https://github.com/yargs/yargs-parser/compare/v4.2.0...v4.2.1) (2017-01-02)
+
+
+### Bug Fixes
+
+* flatten/duplicate regression ([#75](https://github.com/yargs/yargs-parser/issues/75)) ([68d68a0](https://github.com/yargs/yargs-parser/commit/68d68a0))
+
+
+
# [4.2.0](https://github.com/yargs/yargs-parser/compare/v4.1.0...v4.2.0) (2016-12-01)
diff --git a/index.js b/index.js
index cdb5fc55..1a04d559 100644
--- a/index.js
+++ b/index.js
@@ -325,8 +325,10 @@ function parse (args, opts) {
i = ii
argsToSet.push(args[ii])
}
- if (multipleArrayFlag && !configuration['flatten-duplicate-arrays']) {
- setArg(key, argsToSet)
+ if (multipleArrayFlag) {
+ setArg(key, argsToSet.map(function (arg) {
+ return processValue(key, arg)
+ }))
} else {
argsToSet.forEach(function (arg) {
setArg(key, arg)
@@ -339,33 +341,13 @@ function parse (args, opts) {
function setArg (key, val) {
unsetDefaulted(key)
- // handle parsing boolean arguments --foo=true --bar false.
- if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
- if (typeof val === 'string') val = val === 'true'
- }
-
if (/-/.test(key) && !(flags.aliases[key] && flags.aliases[key].length) && configuration['camel-case-expansion']) {
var c = camelCase(key)
flags.aliases[key] = [c]
newAliases[c] = true
}
- var value = val
- if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) {
- if (isNumber(val)) value = Number(val)
- if (!isUndefined(val) && !isNumber(val) && checkAllAliases(key, flags.numbers)) value = NaN
- }
-
- // increment a count given as arg (either no value or value parsed as boolean)
- if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) {
- value = increment
- }
-
- // Set normalized value when key is in 'normalize' and in 'arrays'
- if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) {
- if (Array.isArray(val)) value = val.map(path.normalize)
- else value = path.normalize(val)
- }
+ var value = processValue(key, val)
var splitKey = key.split('.')
setKey(argv, splitKey, value)
@@ -407,6 +389,31 @@ function parse (args, opts) {
}
}
+ function processValue (key, val) {
+ // handle parsing boolean arguments --foo=true --bar false.
+ if (checkAllAliases(key, flags.bools) || checkAllAliases(key, flags.counts)) {
+ if (typeof val === 'string') val = val === 'true'
+ }
+
+ var value = val
+ if (!checkAllAliases(key, flags.strings) && !checkAllAliases(key, flags.coercions)) {
+ if (isNumber(val)) value = Number(val)
+ if (!isUndefined(val) && !isNumber(val) && checkAllAliases(key, flags.numbers)) value = NaN
+ }
+
+ // increment a count given as arg (either no value or value parsed as boolean)
+ if (checkAllAliases(key, flags.counts) && (isUndefined(value) || typeof value === 'boolean')) {
+ value = increment
+ }
+
+ // Set normalized value when key is in 'normalize' and in 'arrays'
+ if (checkAllAliases(key, flags.normalize) && checkAllAliases(key, flags.arrays)) {
+ if (Array.isArray(val)) value = val.map(path.normalize)
+ else value = path.normalize(val)
+ }
+ return value
+ }
+
// set args from config.json file, this should be
// applied last so that defaults can be applied.
function setConfig (argv) {
@@ -551,15 +558,23 @@ function parse (args, opts) {
var key = keys[keys.length - 1]
+ var isTypeArray = checkAllAliases(key, flags.arrays)
+ var isValueArray = Array.isArray(value)
+ var duplicate = configuration['duplicate-arguments-array']
+
if (value === increment) {
o[key] = increment(o[key])
- } else if (o[key] === undefined && checkAllAliases(key, flags.arrays)) {
- o[key] = Array.isArray(value) && configuration['flatten-duplicate-arrays'] ? value : [value]
- } else if (o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts)) {
- o[key] = value
} else if (Array.isArray(o[key])) {
- o[key].push(value)
- } else if (configuration['duplicate-arguments-array']) {
+ if (duplicate && isTypeArray && isValueArray) {
+ o[key] = configuration['flatten-duplicate-arrays'] ? o[key].concat(value) : [o[key]].concat([value])
+ } else if (!duplicate && Boolean(isTypeArray) === Boolean(isValueArray)) {
+ o[key] = value
+ } else {
+ o[key] = o[key].concat([value])
+ }
+ } else if (o[key] === undefined && isTypeArray) {
+ o[key] = isValueArray ? value : [value]
+ } else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.bools) || checkAllAliases(keys.join('.'), flags.bools) || checkAllAliases(key, flags.counts))) {
o[key] = [ o[key], value ]
} else {
o[key] = value
diff --git a/package.json b/package.json
index 953897e2..9b3ddd55 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "yargs-parser",
- "version": "4.2.0",
+ "version": "4.2.1",
"description": "the mighty option parser used by yargs",
"main": "index.js",
"scripts": {
@@ -31,7 +31,7 @@
"mocha": "^3.0.1",
"nyc": "^10.0.0",
"standard": "^8.0.0",
- "standard-version": "^3.0.0"
+ "standard-version": "^4.0.0"
},
"dependencies": {
"camelcase": "^3.0.0"
diff --git a/test/yargs-parser.js b/test/yargs-parser.js
index 5d4243aa..c9c59993 100644
--- a/test/yargs-parser.js
+++ b/test/yargs-parser.js
@@ -1374,11 +1374,16 @@ describe('yargs-parser', function () {
})
describe('array', function () {
- it('should group values into an array if the same option is specified multiple times', function () {
- var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'])
+ it('should group values into an array if the same option is specified multiple times (duplicate-arguments-array=true)', function () {
+ var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'], {configuration: {'duplicate-arguments-array': true}})
parse.should.have.property('v').and.deep.equal(['a', 'b', 'c'])
parse.should.have.property('_').with.length(0)
})
+ it('should keep only the last value if the same option is specified multiple times (duplicate-arguments-false)', function () {
+ var parse = parser(['-v', 'a', '-v', 'b', '-v', 'c'], {configuration: {'duplicate-arguments-array': false}})
+ parse.should.have.property('v').and.equal('c')
+ parse.should.have.property('_').with.length(0)
+ })
it('should default an array to an empty array if passed as first option followed by another', function () {
var result = parser(['-a', '-b'], {
@@ -2012,6 +2017,182 @@ describe('yargs-parser', function () {
parsed['x'].should.deep.equal(['a', 'b'])
})
})
+
+ describe('duplicate-arguments-array VS flatten-duplicate-arrays', function () {
+ /*
+ duplicate=false, flatten=false
+ type=array
+ [-x 1 2 3] => [1, 2, 3]
+ [-x 1 2 3 -x 2 3 4] => [2, 3, 4]
+ type=string/number/etc
+ [-x 1 -x 2 -x 3] => 3
+
+ duplicate=false, flatten=true
+ type=array
+ [-x 1 2 3] => [1, 2, 3]
+ [-x 1 2 3 -x 2 3 4] => [2, 3, 4]
+ type=string/number/etc
+ [-x 1 -x 2 -x 3] => 3
+
+ duplicate=true, flatten=true
+ type=array
+ [-x 1 2 3] => [1, 2, 3]
+ [-x 1 2 3 -x 2 3 4] => [1, 2, 3, 2, 3, 4]
+ type=string/number/etc
+ [-x 1 -x 2 -x 3] => [1, 2, 3]
+
+ duplicate=true, flatten=false
+ type=array
+ [-x 1 2 3] => [1, 2, 3]
+ [-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [2, 3, 4]]
+ type=string/number/etc
+ [-x 1 -x 2 -x 3] => [1, 2, 3]
+ */
+ describe('duplicate=false, flatten=false,', function () {
+ describe('type=array', function () {
+ it('[-x 1 2 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 2 3', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ it('[-x 1 2 3 -x 2 3 4] => [2, 3, 4]', function () {
+ var parsed = parser('-x 1 2 3 -x 2 3 4', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal([2, 3, 4])
+ })
+ })
+ describe('type=number', function () {
+ it('[-x 1 -x 2 -x 3] => 3', function () {
+ var parsed = parser('-x 1 -x 2 -x 3', {
+ number: 'x',
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal(3)
+ })
+ })
+ })
+ describe('duplicate=false, flatten=true,', function () {
+ describe('type=array', function () {
+ it('[-x 1 2 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 2 3', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ it('[-x 1 2 3 -x 2 3 4] => [2, 3, 4]', function () {
+ var parsed = parser('-x 1 2 3 -x 2 3 4', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal([2, 3, 4])
+ })
+ })
+ describe('type=number', function () {
+ it('[-x 1 -x 2 -x 3] => 3', function () {
+ var parsed = parser('-x 1 -x 2 -x 3', {
+ number: 'x',
+ configuration: {
+ 'duplicate-arguments-array': false,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal(3)
+ })
+ })
+ })
+ describe('duplicate=true, flatten=true,', function () {
+ describe('type=array', function () {
+ it('[-x 1 2 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 2 3', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ it('[-x 1 2 3 -x 2 3 4] => [1, 2, 3, 2, 3, 4]', function () {
+ var parsed = parser('-x 1 2 3 -x 2 3 4', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3, 2, 3, 4])
+ })
+ })
+ describe('type=number', function () {
+ it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 -x 2 -x 3', {
+ number: 'x',
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': true
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ })
+ })
+ describe('duplicate=true, flatten=false,', function () {
+ describe('type=array', function () {
+ it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 -x 2 -x 3', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ it('[-x 1 2 3 -x 2 3 4] => [[1, 2, 3], [ 2, 3, 4]]', function () {
+ var parsed = parser('-x 1 2 3 -x 2 3 4', {
+ array: ['x'],
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal([[1, 2, 3], [2, 3, 4]])
+ })
+ })
+ describe('type=number', function () {
+ it('[-x 1 -x 2 -x 3] => [1, 2, 3]', function () {
+ var parsed = parser('-x 1 -x 2 -x 3', {
+ number: 'x',
+ configuration: {
+ 'duplicate-arguments-array': true,
+ 'flatten-duplicate-arrays': false
+ }
+ })
+ parsed['x'].should.deep.equal([1, 2, 3])
+ })
+ })
+ })
+ })
})
// addresses: https://github.com/yargs/yargs-parser/issues/41