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
Conflicting options with default values (or boolean values) #929
Comments
Similar problem with variadic positional arguments. Maybe because those have a default value of yargs('my-command --update-all')
.command('my-command [things-to-update..]', 'Some description', {
'update-all': {
boolean: true,
conflicts: 'things-to-update',
},
}, function(argv) {
console.log(argv['update-all']);
})
.argv; Expected: log |
@jordansexton any thoughts about what the default behavior should be ... what's weird is that |
Yeah, special preference for This might be accomplished by evaluating conflicting values that are provided as args, and then applying defaults. Alternatively, it could apply defaults/coercion/etc. and then evaluate conflicting values as being values not equal to the respective default values if provided. require('yargs')
.options({
i: {
alias: 'include',
default: false,
describe: 'Include something',
type: 'boolean',
conflicts: 'exclude'
},
e: {
alias: 'exclude',
default: false,
describe: 'Exclude something',
type: 'boolean',
conflicts: 'include'
}
}); I read the intent of the above option declaration is to say "either one can be true, but not both". script # No args, apply defaults. No error.
script --include # Include is true, exclude is default (false). No error.
script -i false -e false # Superfluous, but both match their defaults. No error.
script --include --exclude # Both aren't identical to their defaults. Error! This way, I haven't looked to see how difficult this implementation would be, but what do you think of the reasoning? |
@jordansexton I agree with what you're saying ... I don't think the fact that we've applied a default value for an argument should result in it being flagged as a conflict. Because the default values are applied in the parsing library Do you have any interest in taking a stab at implementing this? |
Yeah, I'll take a look at the code and see if I can get it done. |
@bcoe So, defaults are applied in yargs-parser, which should be okay for what I'm thinking, provided that yargs itself can see the defaults where it would need to @ Lines 324 to 333 in 0e0c58d
Can it? |
Okay, so it looks like https://github.com/yargs/yargs-parser/blob/00bde7d60c433c188f2529a33bab187d40645f7d/index.js#L677-L683 would need to change to include Then Lines 1063 to 1073 in 0e0c58d
argv as well as the defaults to the code from #929 (comment) which can then compare against the value rather than the key.
If this sounds right to you, I'll first open a PR against yargs-parser for the first change and then follow up here. |
I'm considering that |
Hey everyone. I don't know of how much use this sample will be, but it seems booleans and default values aren't the only affected types. The code below is in NodeJs, and the javascript file is called test.js const yargs = require('yargs');
const argv = yargs
.usage('<cmd> args')
.command('hello', 'the best command', {
alias: 'h',
describe: 'Says hello'
}, function (argv) {
console.log(argv);
})
.option('work', {
alias: 'w',
describe: 'does some work',
conflicts: 'run'
})
.option('run', {
alias: 'r',
describe: 'runs something',
conflicts: 'work'
})
.help()
.argv; Executing EDIT: Embarrassing... I was also using version 8.0.2. Updating to 9.0.1 fixed the issue. Thank you @quilicicf |
Hi I've bumped into the same issue as @zzharryzz and resorted to using the check method instead. EDIT: my bad, works like a charm with version 9.0.1 (was using 8.0.2). |
I still get this problem on 9.0.1... it seems boolean options always conflict. |
Yup, my problem with string/integer parameters vanished with version 9 but there's still an issue with booleans. Check out this code for an example. |
Just ran into this bug now. For now, I'm setting |
I'm running into this issue as well; it makes it impossible to have mutually exclusive options where one or both are booleans. @bcoe what I would expect is that if the argument is a boolean, it only considers it "set" if it's |
Bug still confirmed for yargs 11. Options always conflict with boolean arguments (with a 'false' default value). |
No, sorry, I haven't made any progress on this. I worked around it by just not using defaults for booleans, and then forgot to look into it beyond the comments above. |
I ran into a similar issue, and what fixed it for me was changing defaults to undefined... .option('debug', {
alias: 'd',
type: 'boolean',
describe: 'logs all debug messages',
conflicts: ['silent', 'quiet', 'verbose'],
default: undefined
})
.option('quiet', {
alias: 'q',
type: 'boolean',
describe: 'log only warnings',
conflicts: ['silent', 'verbose', 'debug'],
default: undefined
})
.option('silent', {
alias: 's',
type: 'boolean',
describe: 'turn off logging',
conflicts: ['quiet', 'verbose', 'debug'],
default: undefined
})
.option('verbose', {
alias: 'V',
type: 'boolean',
describe: 'enables verbose logging',
conflicts: ['silent', 'quiet', 'debug'],
default: undefined
}) note above, without |
Just ran into this issue. Two options that have a default of |
While I advocated not changing the existing setup (thinking about potential dependent package breakage issues), here's additional discussion in the yargs-parser concerning changing the default boolean to |
I am also running into this issue, but for type "count." In my case, I have a "debug" count option that increases the logging level, which should conflict with a "loglevel" option that explicitly sets the logging level. So, specifying loglevel always results in "Arguments loglevel and debug are mutually exclusive" even when debug is not specified (but has a default value of 0). |
This seems to be fixed in yargs v12. |
if it was fixed in yargs 12 it is back in two boolean options with default |
@anentropic would you be able to provide a minimal example of the bug in action, we should put a test around this if it was a regression. |
sure, my code is basically: /**
* @param {Array<string>} rawArgs - i.e. from `process.argv`
* @returns {Object} parsed args
*/
export function parseArgs(rawArgs) {
return yargs
.command('$0 <files...>', 'My tool command', (yargs) => {
yargs
.option('no-color', {
alias: 'n',
type: 'boolean',
default: undefined, // default: false triggers conflict warning by yargs
describe:
`Monochrome output only`
})
.option('force-color', {
alias: 'c',
type: 'boolean',
default: undefined, // default: false triggers conflict warning by yargs
conflicts: 'no-color',
describe:
`When running as a pre-commit hook we are unable to detect if the ` +
`terminal supports colored output. If you want to see colored ` +
`output then set this flag.`
});
})
.help()
.parse(rawArgs.slice(2))
;
} |
This issue is solved now for booleans: a conflict will be triggered only if you explicitely set a default value (as for other types). |
Using
conflicts
with an option that has a default value, or a boolean option (which is automatically set tofalse
even if a default value is not provided) always throws an error, because the conflicting option name will always be defined.The text was updated successfully, but these errors were encountered: