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(builder): nested builder is now awaited #1925

Merged
merged 1 commit into from Apr 26, 2021
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
21 changes: 16 additions & 5 deletions lib/command.ts
Expand Up @@ -307,7 +307,9 @@ export class CommandInstance {
parentCommands: string[],
commandIndex: number,
helpOnly: boolean
): {aliases: Dictionary<string[]>; innerArgv: Arguments} {
):
| {aliases: Dictionary<string[]>; innerArgv: Arguments}
| Promise<{aliases: Dictionary<string[]>; innerArgv: Arguments}> {
// A null command indicates we are running the default command,
// if this is the case, we should show the root usage instructions
// rather than the usage instructions for the nested default command:
Expand All @@ -334,10 +336,19 @@ export class CommandInstance {
commandIndex,
helpOnly
);
return {
aliases: (innerYargs.parsed as DetailedArguments).aliases,
innerArgv: innerArgv as Arguments,
};
if (isPromise(innerArgv)) {
return innerArgv.then(argv => {
return {
aliases: (innerYargs.parsed as DetailedArguments).aliases,
innerArgv: argv,
};
});
} else {
return {
aliases: (innerYargs.parsed as DetailedArguments).aliases,
innerArgv: innerArgv,
};
}
}
private shouldUpdateUsage(yargs: YargsInstance) {
return (
Expand Down
10 changes: 4 additions & 6 deletions lib/yargs-factory.ts
Expand Up @@ -1032,11 +1032,7 @@ export class YargsInstance {
);
this[kFreeze](); // Push current state of parser onto stack.
if (typeof args === 'undefined') {
const argv = this[kRunYargsParserAndExecuteCommands](this.#processArgs);
const tmpParsed = this.parsed;
this[kUnfreeze](); // Pop the stack.
this.parsed = tmpParsed;
return argv;
args = this.#processArgs;
}

// a context object can optionally be provided, this allows
Expand All @@ -1063,6 +1059,7 @@ export class YargsInstance {
args,
!!shortCircuit
);
const tmpParsed = this.parsed;
this.#completion!.setParsed(this.parsed as DetailedArguments);
if (isPromise(parsed)) {
return parsed
Expand All @@ -1082,10 +1079,12 @@ export class YargsInstance {
})
.finally(() => {
this[kUnfreeze](); // Pop the stack.
this.parsed = tmpParsed;
});
} else {
if (this.#parseFn) this.#parseFn(this.#exitError, parsed, this.#output);
this[kUnfreeze](); // Pop the stack.
this.parsed = tmpParsed;
}
return parsed;
}
Expand Down Expand Up @@ -1983,7 +1982,6 @@ export class YargsInstance {
const handlerKeys = this.#command.getCommands();
const requestCompletions = this.#completion!.completionKey in argv;
const skipRecommendation = helpOptSet || requestCompletions || helpOnly;

if (argv._.length) {
if (handlerKeys.length) {
let firstUnknownCommand;
Expand Down
56 changes: 56 additions & 0 deletions test/command.cjs
Expand Up @@ -2065,6 +2065,62 @@ describe('Command', () => {
argv.help.should.equal(true);
});
});
// Refs: https://github.com/yargs/yargs/issues/1917
it('allows command to be defined in async builder', async () => {
let invoked = false;
await yargs('alpha beta')
.strict()
.command({
command: 'alpha',
describe: 'A',
builder: async yargs => {
await wait();
yargs
.command({
command: 'beta',
describe: 'B',
handler: () => {
invoked = true;
},
})
.demandCommand(1);
},
})
.demandCommand(1)
.parse();
assert.strictEqual(invoked, true);
});
it('allows deeply nested command to be defined in async builder', async () => {
let invoked = false;
await yargs('alpha beta gamma')
.strict()
.command('alpha', 'A', async yargs => {
await wait();
yargs
.command({
command: 'beta',
describe: 'B',
builder: async yargs => {
await wait();
return yargs.command(
'gamma',
'C',
async () => {
await wait();
},
async () => {
await wait();
invoked = true;
}
);
},
})
.demandCommand(1);
})
.demandCommand(1)
.parse();
assert.strictEqual(invoked, true);
});
});

describe('builder', () => {
Expand Down
1 change: 0 additions & 1 deletion test/usage.cjs
Expand Up @@ -596,7 +596,6 @@ describe('usage tests', () => {
// ignore the error, we only test the output here
}
});
console.info(r);
r.errors
.join('\n')
.split(/\n+/)
Expand Down