Skip to content

fix(cli): migrate remaining StringSlice flags onto legacyStringSliceFlag builder (CLI-2005) - #6010

Merged
Coly010 merged 6 commits into
developfrom
columferry/cli-2005-migrate-remaining-pflag-stringslice-call-sites-onto
Aug 3, 2026
Merged

fix(cli): migrate remaining StringSlice flags onto legacyStringSliceFlag builder (CLI-2005)#6010
Coly010 merged 6 commits into
developfrom
columferry/cli-2005-migrate-remaining-pflag-stringslice-call-sites-onto

Conversation

@Coly010

@Coly010 Coly010 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

What changed

Follow-up to CLI-1983 (#5975), from kanadgupta's review: the seven remaining hand-rolled pflag StringSliceVar call sites still mapped malformed-CSV failures to a bare err.message, so their stderr missed pflag's invalid argument %q for %q flag: ... framing. All of them now route through the shared legacyStringSliceFlag builder (src/legacy/shared/legacy-string-slice-flag.ts):

  • sso add --domains
  • sso update --domains / --add-domains / --remove-domains
  • postgres-config update --config
  • postgres-config delete --config
  • start --exclude / -x
  • status --override-name / --exclude

The builder gains an optional { alias } parameter because start --exclude is the one site whose Go counterpart is a StringSliceVarP with a shorthand (cmd/start.go:58): pflag frames such diagnostics with both spellings — invalid argument %q for "-x, --exclude" flag: ... (pflag v1.0.10 errors.go:108-117 branches on flag.Shorthand) — regardless of which spelling the user typed, so the alias has to be registered inside the builder for the framing to come out right.

Flag.withDefault([] as ReadonlyArray<string>) was dropped from the migrated flag definitions: Flag.atLeast(0) already yields [] when the flag is unset (covered by the existing "defaults to an empty array when unset" unit tests), and --help output was verified byte-identical before/after for all six commands.

Per-site Go parity verification

Every rendered line was verified against the Go binary built from apps/cli-go (pflag v1.0.10 → encoding/csv). All seven sites' malformed-CSV stderr changes user-visibly — from the bare parse-error text to the full pflag line:

Site Go framing Example (Go-verified, now byte-matched by TS)
sso add --domains "--domains" invalid argument "a\"b" for "--domains" flag: parse error on line 1, column 2: bare " in non-quoted-field
sso update --domains "--domains" same as above
sso update --add-domains "--add-domains" invalid argument "\"x" for "--add-domains" flag: parse error on line 1, column 3: extraneous or missing " in quoted-field
sso update --remove-domains "--remove-domains" same shape as --add-domains
postgres-config update --config "--config" invalid argument "a\"b" for "--config" flag: parse error on line 1, column 2: bare " in non-quoted-field
postgres-config delete --config "--config" invalid argument "\"max_connections" for "--config" flag: parse error on line 1, column 17: extraneous or missing " in quoted-field
start --exclude / -x "-x, --exclude" invalid argument "a\"b" for "-x, --exclude" flag: parse error on line 1, column 2: bare " in non-quoted-field
status --override-name "--override-name" invalid argument "\"api.url=FOO" for "--override-name" flag: parse error on line 1, column 13: extraneous or missing " in quoted-field
status --exclude "--exclude" invalid argument "a\"b" for "--exclude" flag: parse error on line 1, column 2: bare " in non-quoted-field

For postgres-config, the parse error also correctly precedes the --experimental gate (cobra parses flags before PersistentPreRunE), asserted in the experimental-gate integration suite.

Multiline / blank-line semantics findings

CLI-1983's parser rewrite changed legacyParseStringSliceFlag itself, so all seven sibling sites silently inherited the first-record-only / EOF-on-blank semantics. I verified each site against the Go binary:

  • First-record-only: --<flag> $'a\nb"c' raises no parse error in Go at any of the seven sites (pflag calls csv.Reader.Read() once; the malformed second line is silently dropped). Observable proof for start: start -x $'a\nb"c' warns The following container names are not valid to exclude: a — only the first record survives. TS matches.
  • Blank-only → EOF: --<flag> $'\n' fails in Go with invalid argument "\n" for "--<flag>" flag: EOF at every site (with the -x, --exclude framing on start). TS matches.
  • No sibling site's existing tests asserted stale pre-rewrite behaviour — they simply had no multiline/blank-only coverage at all, and their malformed-CSV tests only asserted Exit.isFailure without the message. This PR adds exact-message assertions per flag plus first-record-only and blank-only-EOF vectors per site.

Test coverage added

  • Per-site unit tests: exact pflag-framed diagnostics (including the shorthand framing for start), first-record-only multiline vectors, blank-only EOF vectors.
  • Per-family integration tests running the whole command tree (Command.runWith) and asserting the exact rendered message via normalizeCause, mirroring the network-bans/network-restrictions prior art from CLI-1983: new sso.string-slice-flags.integration.test.ts, start.string-slice-flags.integration.test.ts, status.string-slice-flags.integration.test.ts, plus malformed-CSV cases in the existing postgres-config.experimental-gate.integration.test.ts.
  • start's --exclude flag is hoisted to an exported legacyStartExcludeFlag (mirroring status/sso conventions) so it is unit-testable.
  • SIDE_EFFECTS.md for all six commands gains the parse-time failure exit-code row (mirroring CLI-1983's doc updates).
  • Stale comments referencing the deleted csvStringSliceFlag helper in legacy-db-target-flags.ts/.unit.test.ts were updated; all helper-built flag names remain hand-registered in VALUE_CONSUMING_LONG_FLAGS, so telemetry argv parsing is unaffected.

Overlap note: PR #5974

Open PR #5974 (columferry/cli-1982-...) touches sso command files (sso.pflag-reconcile.ts, add/update handlers). This PR's sso changes are deliberately minimal — the flag definition blocks in add.command.ts/update.command.ts, their unit tests, one new family-level integration test file, and one SIDE_EFFECTS.md row. Whoever merges second should re-verify the sso flag definitions still route through legacyStringSliceFlag after conflict resolution.

Review notes (deliberately left open)

  • The --schema slice-flag family (gen types, db lint/dump/pull/diff, db schema declarative generate) still uses the hand-rolled Flag.mapTryCatch(legacyParseSchemaFlags, err => err.message) pattern via legacy-schema-flags.ts. It is not in CLI-2005's scope (and several of those are StringSliceVarP with -s shorthands needing their own per-site Go verification) — candidate for a follow-up issue.
  • The pathological double-error case (-o bad plus malformed CSV in one invocation): TS surfaces the CSV parse error while Go's winner depends on argv order; both exit non-zero. Same accepted approximation as CLI-1983, already documented on the network-bans/network-restrictions flag comments.
  • cli-go:lint:check fails with 5 pre-existing gosec findings unrelated to this change (no Go files touched).

Fixes CLI-2005

…lag builder (CLI-2005)

All seven remaining hand-rolled pflag StringSliceVar call sites (sso add
--domains; sso update --domains/--add-domains/--remove-domains;
postgres-config update/delete --config; start --exclude/-x; status
--override-name/--exclude) now route through the shared
legacyStringSliceFlag builder, so their malformed-CSV stderr byte-matches
Go pflag's 'invalid argument %q for %q flag: ...' diagnostic. The builder
gains an optional alias parameter for start's StringSliceVarP shorthand,
which pflag frames as '-x, --exclude'. Every rendered line and the
multiline/blank-only semantics were verified against the real Go binary.

Fixes CLI-2005
@Coly010

Coly010 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 8f6ad2ef95

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…5-migrate-remaining-pflag-stringslice-call-sites-onto
@Coly010
Coly010 marked this pull request as ready for review July 31, 2026 09:55
@Coly010
Coly010 requested a review from a team as a code owner July 31, 2026 09:55
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Supabase CLI preview

npx --yes https://pkg.pr.new/supabase/cli/supabase@55a06c905f841f47172bfe70748a9080e0f1f3ab

Preview package for commit 55a06c9.

@Coly010 Coly010 self-assigned this Jul 31, 2026

@kanadgupta kanadgupta left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two minor cleanup suggestions per Claude otherwise LGTM

Comment thread apps/cli/src/legacy/shared/legacy-db-target-flags.unit.test.ts Outdated
Comment thread apps/cli/src/legacy/commands/sso/update/update.command.ts
…unset-default coverage (CLI-2005)

status.command.ts's slice flags now go through legacyStringSliceFlag (whose
names the completeness scan already can't see), so the exclusion entry was a
no-op that only risked hiding future direct value-flag declarations there.
Also adds the "defaults to an empty array when unset" test for sso update's
three domain flags, matching the coverage already present for sso add,
start, and status.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b9dd061df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/cli/src/legacy/commands/start/start.string-slice-flags.integration.test.ts Outdated
Coly010 added 3 commits August 3, 2026 12:03
…5-migrate-remaining-pflag-stringslice-call-sites-onto

# Conflicts:
#	apps/cli/src/legacy/commands/sso/add/SIDE_EFFECTS.md
#	apps/cli/src/legacy/commands/sso/add/add.command.ts
#	apps/cli/src/legacy/commands/sso/update/SIDE_EFFECTS.md
#	apps/cli/src/legacy/commands/sso/update/update.command.ts
#	apps/cli/src/legacy/commands/start/SIDE_EFFECTS.md
Merging HEAD's legacyStringSliceFlag domains-flag definitions with
develop's auto-merged LEGACY_SSO_NAME_ID_FORMATS hoisting left an
orphaned local NAME_ID_FORMATS const in sso add/update; drop it.
Also reflow the SIDE_EFFECTS.md exit-code tables merged in the
previous commit to satisfy oxfmt.
…lag tests (CLI-2005)

Command.withGlobalFlags only excludes each global flag's context
requirement from the R accumulated on the command SO FAR; applying it
before withSubcommands means it never sees (and can't discharge) the
GlobalFlag context the subcommand's own handler chain reads. Reorder
withSubcommands before withGlobalFlags in both files so the exclusion
covers the whole tree, closing R to never without an `as` cast.
@Coly010
Coly010 added this pull request to the merge queue Aug 3, 2026
Merged via the queue into develop with commit 8df4167 Aug 3, 2026
25 of 27 checks passed
@Coly010
Coly010 deleted the columferry/cli-2005-migrate-remaining-pflag-stringslice-call-sites-onto branch August 3, 2026 12:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants