Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "boolean" flag with "duplicate-arguments-array" #184

Merged
merged 3 commits into from Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 3 additions & 26 deletions index.js
Expand Up @@ -46,7 +46,6 @@ function parse (args, opts) {
counts: {},
normalize: {},
configs: {},
defaulted: {},
nargs: {},
coercions: {},
keys: []
Expand Down Expand Up @@ -132,14 +131,6 @@ function parse (args, opts) {
})

var argv = { _: [] }

Object.keys(flags.bools).forEach(function (key) {
if (Object.prototype.hasOwnProperty.call(defaults, key)) {
setArg(key, defaults[key])
setDefaulted(key)
}
})

var notFlags = []

for (var i = 0; i < args.length; i++) {
Expand Down Expand Up @@ -406,8 +397,6 @@ function parse (args, opts) {
}

function setArg (key, val) {
unsetDefaulted(key)

if (/-/.test(key) && configuration['camel-case-expansion']) {
var alias = key.split('.').map(function (prop) {
return camelCase(prop)
Expand Down Expand Up @@ -560,7 +549,7 @@ function parse (args, opts) {
} else {
// setting arguments via CLI takes precedence over
// values within the config file.
if (!hasKey(argv, fullKey.split('.')) || (flags.defaulted[fullKey]) || (flags.arrays[fullKey] && configuration['combine-arrays'])) {
if (!hasKey(argv, fullKey.split('.')) || (flags.arrays[fullKey] && configuration['combine-arrays'])) {
setArg(fullKey, value)
}
}
Expand Down Expand Up @@ -589,7 +578,7 @@ function parse (args, opts) {
return camelCase(key)
})

if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && (!hasKey(argv, keys) || flags.defaulted[keys.join('.')])) {
if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && !hasKey(argv, keys)) {
setArg(keys.join('.'), process.env[envVar])
}
}
Expand Down Expand Up @@ -704,7 +693,7 @@ function parse (args, opts) {
}
} 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))) {
} else if (duplicate && !(o[key] === undefined || checkAllAliases(key, flags.counts))) {
o[key] = [ o[key], value ]
} else {
o[key] = value
Expand Down Expand Up @@ -762,18 +751,6 @@ function parse (args, opts) {
return isSet
}

function setDefaulted (key) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned that we're completely removing the setDefaulted functionality, which I see used here:

        if (((configOnly && flags.configs[keys.join('.')]) || !configOnly) && (!hasKey(argv, keys) || flags.defaulted[keys.join('.')])) {
          setArg(keys.join('.'), process.env[envVar])
        }

and, here:

        if (!hasKey(argv, fullKey.split('.')) || (flags.defaulted[fullKey]) || (flags.arrays[fullKey] && configuration['combine-arrays'])) {
          setArg(fullKey, value)
        }

If it's true that we're not using this functionality, awesome let's get rid of it -- I'm just slightly worried we might be missing a unit tests for this historic behavior ... I tried to perform a git blame and it looks like this feature has been around forever.

Copy link
Contributor Author

@juergba juergba Jun 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var args = parse('', {
  boolean: ['file'],
  // default: {'file': true},
  configObjects: [{'file': false}]
})

before PR #119 the behavior was:

  • there is no --file in CLI and no user set default, but we set an imlicit false => file: false
  • set defaulted[file] = true
  • while processing configObect the user input overrides the defaulted value

after PR #119 the behavior is:

  • there is no --file in CLI and no user set default, so we don't set this property
  • therefore we don't set defaulted neither
  • while processing configObect the user input is set
  • in case of an user set default: applyDefaultsAndAliases() does this job for number, string and boolean the identical way.

IMO this defaulted can be explained with historic reasons and can be removed completely.
Now defaulted is not set anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set-placeholder-key:
when truthy, setPlaceholderKeys() sets the value to undefinded, very similar to applyDefaultsAndAliases() which sets a user default value instead. So in this case we don't need defaultedneither.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juergba do you want to go ahead and submit a patch that completely removes the defaulted behavior then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, done.

[].concat(flags.aliases[key] || [], key).forEach(function (k) {
flags.defaulted[k] = true
})
}

function unsetDefaulted (key) {
[].concat(flags.aliases[key] || [], key).forEach(function (k) {
delete flags.defaulted[k]
})
}

// make a best effor to pick a default value
// for an option based on name and type.
function defaultValue (key) {
Expand Down
54 changes: 51 additions & 3 deletions test/yargs-parser.js
Expand Up @@ -1108,7 +1108,7 @@ describe('yargs-parser', function () {
})
})

describe('with implied false default', function () {
describe('without any default value', function () {
var opts = null

beforeEach(function () {
Expand All @@ -1125,8 +1125,8 @@ describe('yargs-parser', function () {
parser(['--no-flag'], opts).flag.should.be.false // eslint-disable-line
})

it('should set false if no flag in arg', function () {
expect(parser([], opts).flag).to.be.undefined // eslint-disable-line
it('should not add property if no flag in arg', function () {
parser([''], opts).should.not.have.property('flag')
})
})

Expand Down Expand Up @@ -2334,6 +2334,18 @@ describe('yargs-parser', function () {
parsed['x'].should.deep.equal(3)
})
})
describe('type=boolean', function () {
it('[-x true -x true -x false] => false', function () {
var parsed = parser('-x true -x true -x false', {
boolean: ['x'],
configuration: {
'duplicate-arguments-array': false,
'flatten-duplicate-arrays': false
}
})
parsed['x'].should.deep.equal(false)
})
})
})
describe('duplicate=false, flatten=true,', function () {
describe('type=array', function () {
Expand Down Expand Up @@ -2370,6 +2382,18 @@ describe('yargs-parser', function () {
parsed['x'].should.deep.equal(3)
})
})
describe('type=boolean', function () {
it('[-x true -x true -x false] => false', function () {
var parsed = parser('-x true -x true -x false', {
boolean: ['x'],
configuration: {
'duplicate-arguments-array': false,
'flatten-duplicate-arrays': true
}
})
parsed['x'].should.deep.equal(false)
})
})
})
describe('duplicate=true, flatten=true,', function () {
describe('type=array', function () {
Expand Down Expand Up @@ -2406,6 +2430,18 @@ describe('yargs-parser', function () {
parsed['x'].should.deep.equal([1, 2, 3])
})
})
describe('type=boolean', function () {
it('[-x true -x true -x false] => [true, true, false]', function () {
var parsed = parser('-x true -x true -x false', {
boolean: ['x'],
configuration: {
'duplicate-arguments-array': true,
'flatten-duplicate-arrays': true
}
})
parsed['x'].should.deep.equal([true, true, false])
})
})
})
describe('duplicate=true, flatten=false,', function () {
describe('type=array', function () {
Expand Down Expand Up @@ -2442,6 +2478,18 @@ describe('yargs-parser', function () {
parsed['x'].should.deep.equal([1, 2, 3])
})
})
describe('type=boolean', function () {
it('[-x true -x true -x false] => [true, true, false]', function () {
var parsed = parser('-x true -x true -x false', {
boolean: ['x'],
configuration: {
'duplicate-arguments-array': true,
'flatten-duplicate-arrays': false
}
})
parsed['x'].should.deep.equal([true, true, false])
})
})
})
})

Expand Down