From 5c7e534229197d32ffc605f19394300c6ebdf8ac Mon Sep 17 00:00:00 2001 From: peternhale Date: Wed, 12 Apr 2023 14:55:27 -0600 Subject: [PATCH] fix: jsonEnabled not handling after pass-through (#687) * fix: jsonEnabled does not consider json flag appearing after pass-through @W-13012400@ * test: with some extra params --------- Co-authored-by: mshanemc --- src/command.ts | 30 ++++++++- test/command/command.test.ts | 119 ++++++++++++++++++++++++++++++++++ test/interfaces/flags.test.ts | 2 + 3 files changed, 150 insertions(+), 1 deletion(-) diff --git a/src/command.ts b/src/command.ts index 9bc47d89e..fc19634c6 100644 --- a/src/command.ts +++ b/src/command.ts @@ -125,6 +125,8 @@ export abstract class Command { public static hasDynamicHelp = false + protected static '_--' = false + protected static _enableJsonFlag = false public static get enableJsonFlag(): boolean { @@ -142,6 +144,18 @@ export abstract class Command { } } + public static get '--'(): boolean { + return Command['_--'] + } + + public static set '--'(value: boolean) { + Command['_--'] = value + } + + public get passThroughEnabled(): boolean { + return Command['_--'] + } + /** * instantiate and run the command * @@ -259,8 +273,22 @@ export abstract class Command { } } + /** + * Determine if the command is being run with the --json flag in a command that supports it. + * + * @returns {boolean} true if the command supports json and the --json flag is present + */ public jsonEnabled(): boolean { - return this.ctor.enableJsonFlag && this.argv.includes('--json') + // if the command doesn't support json, return false + if (!this.ctor.enableJsonFlag) return false + // if the command parameter pass through is enabled, return true if the --json flag is before the '--' separator + if (this.passThroughEnabled) { + const ptIndex = this.argv.indexOf('--') + const jsonIndex = this.argv.indexOf('--json') + return jsonIndex > -1 && (ptIndex === -1 || jsonIndex < ptIndex) + } + + return this.argv.includes('--json') } /** diff --git a/test/command/command.test.ts b/test/command/command.test.ts index 15fccf544..583456c4e 100644 --- a/test/command/command.test.ts +++ b/test/command/command.test.ts @@ -449,4 +449,123 @@ describe('command', () => { .do(ctx => expect(ctx.stdout).to.equal('json output: {"a":"foobar"}\n')) .it('test stdout EPIPE swallowed') }) + describe('json enabled and pass-through tests', () => { + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + async run() { + this.log('not json output') + } + } + const cmd = new CMD([], {} as any) + expect(cmd.jsonEnabled()).to.equal(false) + }) + .it('json enabled/pass through disabled/no --json flag/jsonEnabled() should be false') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + async run() {} + } + const cmd = new CMD(['--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(true) + }) + .it('json enabled/pass through disabled/--json flag before --/jsonEnabled() should be true') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + static '--' = true + async run() { + const {flags} = await cmd.parse(CMD, ['--json']) + expect(flags.json).to.equal(true, 'json flag should be true') + } + } + const cmd = new CMD(['--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(true) + }) + .it('json enabled/pass through enabled/--json flag before --/jsonEnabled() should be true') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + static '--' = true + async run() { + const {flags} = await cmd.parse(CMD, ['--', '--json']) + expect(flags.json).to.equal(false, 'json flag should be false') + expect(this.passThroughEnabled).to.equal(true, 'pass through should be true') + } + } + const cmd = new CMD(['--', '--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(false) + }) + .it('json enabled/pass through enabled/--json flag after --/jsonEnabled() should be false') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + static '--' = true + async run() { + const {flags} = await cmd.parse(CMD, ['--foo', '--json']) + expect(flags.json).to.equal(true, 'json flag should be true') + } + } + const cmd = new CMD(['foo', '--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(true) + }) + .it('json enabled/pass through enabled/--json flag before --/extra param/jsonEnabled() should be true') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + static '--' = true + async run() { + const {flags} = await cmd.parse(CMD, ['--foo', '--', '--json']) + expect(flags.json).to.equal(false, 'json flag should be false') + expect(this.passThroughEnabled).to.equal(true, 'pass through should be true') + } + } + const cmd = new CMD(['--foo', '--', '--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(false) + }) + .it('json enabled/pass through enabled/--json flag after --/extra param/jsonEnabled() should be false') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = true + static '--' = true + async run() {} + } + const cmd = new CMD(['--json', '--'], {} as any) + expect(cmd.jsonEnabled()).to.equal(true) + }) + .it('json enabled/pass through enabled/--json flag before --/jsonEnabled() should be true') + + fancy + .stdout() + .do(async () => { + class CMD extends Command { + static enableJsonFlag = false + static '--' = true + async run() {} + } + const cmd = new CMD(['--json'], {} as any) + expect(cmd.jsonEnabled()).to.equal(false) + }) + .it('json disabled/pass through enable/--json flag before --/jsonEnabled() should be false') + }) }) diff --git a/test/interfaces/flags.test.ts b/test/interfaces/flags.test.ts index 0573c25c3..cfd0c4e23 100644 --- a/test/interfaces/flags.test.ts +++ b/test/interfaces/flags.test.ts @@ -126,6 +126,8 @@ class MyCommand extends BaseCommand { defaultArrayFlag: arrayFlag({default: ['foo', 'bar']}), } + public static '--' = true + public flags!: MyFlags public async run(): Promise {