diff --git a/src/cliOutput.ts b/src/cliOutput.ts index e175983e4c..a1a6522d56 100644 --- a/src/cliOutput.ts +++ b/src/cliOutput.ts @@ -18,15 +18,25 @@ const VALUED_OUTPUT_FLAGS = new Set([ */ export const normalizeCliOutputArguments = ( arguments_: readonly string[], -): string[] => - arguments_.flatMap((argument) => { +): string[] => { + const normalized: string[] = []; + for (let index = 0; index < arguments_.length; index += 1) { + const argument = arguments_[index]!; + if (VALUED_OUTPUT_FLAGS.has(argument) && arguments_[index + 1]) { + // Incur consumes a nonempty spaced value before looking for more flags. + // Its contents belong to that option, even when they look like a flag. + normalized.push(argument, arguments_[index + 1]!); + index += 1; + continue; + } const separator = argument.indexOf("="); - if (separator < 0) return [argument]; const flag = argument.slice(0, separator); - return VALUED_OUTPUT_FLAGS.has(flag) - ? [flag, argument.slice(separator + 1)] - : [argument]; - }); + if (separator >= 0 && VALUED_OUTPUT_FLAGS.has(flag)) + normalized.push(flag, argument.slice(separator + 1)); + else normalized.push(argument); + } + return normalized; +}; export type CliOutputArgumentValidation = | { readonly ok: true } diff --git a/tests/boundary/cli/cliOutput.test.ts b/tests/boundary/cli/cliOutput.test.ts index 351a49892c..e26b6d84ef 100644 --- a/tests/boundary/cli/cliOutput.test.ts +++ b/tests/boundary/cli/cliOutput.test.ts @@ -60,6 +60,39 @@ describe("CLI output argument boundary", () => { }); describe("CLI output flag value forms", () => { + it.each(["--filter-output", "--format", "--token-limit", "--token-offset"])( + "preserves a flag-shaped spaced value owned by %s", + (flag) => { + expect( + normalizeCliOutputArguments([ + flag, + "--format=json", + "providers", + "--json", + ]), + ).toEqual([flag, "--format=json", "providers", "--json"]); + }, + ); + + workspaceCliTest( + "keeps a flag-shaped filter value equivalent in spaced and equals forms", + async ({ cli }) => { + for (const filter of [ + ["--filter-output", "--format=json"], + ["--filter-output=--format=json"], + ]) { + const result = await cli.run({ + arguments: [...filter, "providers", "--json"], + timeoutMs: 10_000, + }); + expect(result.exitCode).toBe(0); + expect(JSON.parse(result.stdout)).toEqual({}); + expect(result.stderr).toBe(""); + } + }, + CLI_INTEGRATION_TIMEOUT_MS, + ); + it("splits only the equals forms of valued output flags", () => { expect( normalizeCliOutputArguments([