Skip to content

Commit

Permalink
fix: passed arguments should take precedence over values in config (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jly36963 committed May 14, 2022
1 parent e0823dd commit 4dac5b8
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
11 changes: 6 additions & 5 deletions lib/command.ts
Expand Up @@ -593,19 +593,20 @@ export class CommandInstance {
positionalKeys.push(...parsed.aliases[key]);
});

const defaults = yargs.getOptions().default;
Object.keys(parsed.argv).forEach(key => {
if (positionalKeys.includes(key)) {
// any new aliases need to be placed in positionalMap, which
// is used for validation.
if (!positionalMap[key]) positionalMap[key] = parsed.argv[key];
// Addresses: https://github.com/yargs/yargs/issues/1637
// If both positionals/options provided, no default was set,
// If both positionals/options provided,
// and no default or config values were set for that key,
// and if at least one is an array: don't overwrite, combine.
if (
!Object.hasOwnProperty.call(defaults, key) &&
Object.hasOwnProperty.call(argv, key) &&
Object.hasOwnProperty.call(parsed.argv, key) &&
!yargs.isInConfigs(key) &&
!yargs.isDefaulted(key) &&
Object.prototype.hasOwnProperty.call(argv, key) &&
Object.prototype.hasOwnProperty.call(parsed.argv, key) &&
(Array.isArray(argv[key]) || Array.isArray(parsed.argv[key]))
) {
argv[key] = ([] as string[]).concat(argv[key], parsed.argv[key]);
Expand Down
24 changes: 24 additions & 0 deletions lib/yargs-factory.ts
Expand Up @@ -869,6 +869,30 @@ export class YargsInstance {
this.#validation.implies(key, value);
return this;
}
// Check defaults for key (and camel case version of key)
isDefaulted(key: string): boolean {
const {default: defaults} = this.getOptions();
return (
Object.prototype.hasOwnProperty.call(defaults, key) ||
Object.prototype.hasOwnProperty.call(
defaults,
this.#shim.Parser.camelCase(key)
)
);
}
// Check each config for key (and camel case version of key)
isInConfigs(key: string): boolean {
const {configObjects} = this.getOptions();
return (
configObjects.some(c => Object.prototype.hasOwnProperty.call(c, key)) ||
configObjects.some(c =>
Object.prototype.hasOwnProperty.call(
c,
this.#shim.Parser.camelCase(key)
)
)
);
}
locale(locale?: string): YargsInstance | string {
argsert('[string]', [locale], arguments.length);
if (!locale) {
Expand Down
25 changes: 25 additions & 0 deletions test/command.cjs
Expand Up @@ -264,6 +264,31 @@ describe('Command', () => {
.parse('cmd apples cherries grapes');
});

it('does not combine config values and provided values', () => {
yargs('foo bar baz qux')
.command({
command: '$0 <arg-1> [arg-2] [arg-3..]',
desc: 'default description',
builder: yargs =>
yargs
.option('arg-1', {type: 'string'})
.option('arg-2', {type: 'string'})
.option('arg-3', {type: 'string'})
.config({
arg2: 'bar',
arg3: ['baz', 'qux'],
}),
handler: argv => {
argv.arg1.should.equal('foo');
argv.arg2.should.equal('bar');
argv.arg3.should.deep.equal(['baz', 'qux']);
argv['arg-3'].should.deep.equal(['baz', 'qux']);
},
})
.strict()
.parse();
});

it('does not overwrite options in argv if variadic and preserves falsy values', () => {
yargs
.command({
Expand Down

0 comments on commit 4dac5b8

Please sign in to comment.