From b5accd64ccbd3ffb800517fb40d0f59382515fbb Mon Sep 17 00:00:00 2001 From: "Benjamin E. Coe" Date: Sun, 25 Apr 2021 19:26:26 -0700 Subject: [PATCH] fix(builder): nested builder is now awaited (#1925) --- lib/command.ts | 21 +++++++++++++---- lib/yargs-factory.ts | 10 ++++---- test/command.cjs | 56 ++++++++++++++++++++++++++++++++++++++++++++ test/usage.cjs | 1 - 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/lib/command.ts b/lib/command.ts index 83bc17fa5..b1477d24a 100644 --- a/lib/command.ts +++ b/lib/command.ts @@ -307,7 +307,9 @@ export class CommandInstance { parentCommands: string[], commandIndex: number, helpOnly: boolean - ): {aliases: Dictionary; innerArgv: Arguments} { + ): + | {aliases: Dictionary; innerArgv: Arguments} + | Promise<{aliases: Dictionary; 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: @@ -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 ( diff --git a/lib/yargs-factory.ts b/lib/yargs-factory.ts index 983e1ccfa..6dc59ef45 100644 --- a/lib/yargs-factory.ts +++ b/lib/yargs-factory.ts @@ -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 @@ -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 @@ -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; } @@ -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; diff --git a/test/command.cjs b/test/command.cjs index f514d4760..33837fc1a 100644 --- a/test/command.cjs +++ b/test/command.cjs @@ -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', () => { diff --git a/test/usage.cjs b/test/usage.cjs index bea8bd35d..b6e29e190 100644 --- a/test/usage.cjs +++ b/test/usage.cjs @@ -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+/)