Skip to content

Commit

Permalink
Merge branch 'main' into lk/prettier-formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
bcoe committed May 16, 2022
2 parents 8460125 + 1c331f2 commit 3420931
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 8 deletions.
32 changes: 27 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) &&
!this.isInConfigs(yargs, key) &&
!this.isDefaulted(yargs, 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 All @@ -616,6 +617,27 @@ export class CommandInstance {
});
}
}
// Check defaults for key (and camel case version of key)
isDefaulted(yargs: YargsInstance, key: string): boolean {
const {default: defaults} = yargs.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(yargs: YargsInstance, key: string): boolean {
const {configObjects} = yargs.getOptions();
return (
configObjects.some(c => Object.prototype.hasOwnProperty.call(c, key)) ||
configObjects.some(c =>
Object.prototype.hasOwnProperty.call(c, this.shim.Parser.camelCase(key))
)
);
}
runDefaultBuilderOn(yargs: YargsInstance): unknown | Promise<unknown> {
if (!this.defaultCommand) return;
if (this.shouldUpdateUsage(yargs)) {
Expand Down
2 changes: 1 addition & 1 deletion lib/platform-shims/esm.mjs
Expand Up @@ -22,7 +22,7 @@ try {
} catch (e) {
__dirname = process.cwd();
}
const mainFilename = __dirname.split('node_modules')[0];
const mainFilename = __dirname.substring(0, __dirname.lastIndexOf('node_modules'));

export default {
assert: {
Expand Down
2 changes: 1 addition & 1 deletion lib/yargs-factory.ts
Expand Up @@ -871,7 +871,7 @@ export class YargsInstance {
}
locale(locale?: string): YargsInstance | string {
argsert('[string]', [locale], arguments.length);
if (!locale) {
if (locale === undefined) {
this[kGuessLocale]();
return this.#shim.y18n.getLocale();
}
Expand Down
7 changes: 6 additions & 1 deletion locales/ru.json
Expand Up @@ -42,5 +42,10 @@
"Path to JSON config file": "Путь к файлу конфигурации JSON",
"Show help": "Показать помощь",
"Show version number": "Показать номер версии",
"Did you mean %s?": "Вы имели в виду %s?"
"Did you mean %s?": "Вы имели в виду %s?",
"Arguments %s and %s are mutually exclusive": "Аргументы %s и %s являются взаимоисключающими",
"Positionals:": "Позиционные аргументы:",
"command": "команда",
"deprecated": "устар.",
"deprecated: %s": "устар.: %s"
}
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
32 changes: 32 additions & 0 deletions test/yargs.cjs
Expand Up @@ -757,6 +757,38 @@ describe('yargs dsl tests', () => {
r.logs.join(' ').should.match(/Parlay this here code of conduct/);
});

// Addresses: https://github.com/yargs/yargs/issues/2178
it('does not enter infinite loop when locale is invalid', () => {
// Save env vars
const lcAll = process.env.LC_ALL;
const lcMessages = process.env.LC_MESSAGES;
const lang = process.env.LANG;
const language = process.env.LANGUAGE;
// Change
delete process.env.LC_ALL;
delete process.env.LC_MESSAGES;
process.env.LANG = '.UTF-8';
delete process.env.LANGUAGE;
try {
yargs
.command({
command: 'cmd1',
desc: 'cmd1 desc',
builder: () => {},
handler: _argv => {},
})
.parse();
} catch {
expect.fail();
} finally {
// Restore
process.env.LC_ALL = lcAll;
process.env.LC_MESSAGES = lcMessages;
process.env.LANG = lang;
process.env.LANGUAGE = language;
}
});

describe('updateLocale', () => {
it('allows you to override the default locale strings', () => {
const r = checkOutput(() => {
Expand Down

0 comments on commit 3420931

Please sign in to comment.