fix(cli): honor --yes/SUPABASE_YES and Go prompt semantics consistently across confirmation prompts - #5947
Conversation
…firmation sites (CLI-1974) Route every legacy-parity confirmation through the Go-faithful legacyPromptYesNo helper (moved to shared/legacy/ so shared files can use it) instead of per-command shortcuts, matching Go's PromptYesNo (apps/cli-go/internal/utils/console.go:38-107): - viper YES (--yes flag OR SUPABASE_YES env, project .env where Go loads it) auto-confirms everywhere, echoing '<label> [y/N] y' to stderr - non-TTY runs print the label and scan one piped stdin line (100ms), honoring y/n answers instead of hardcoding the default - declined/default paths unchanged Fixed sites: logout (missing echo), projects delete (flag-only yes, no piped read), branches create (yes ignored entirely), secrets unset (hardcoded non-TTY default), bootstrap overwrite (missing echo), functions deploy --prune (flag-only yes, missing echo, Go label bytes), init -i IDE prompts (prompted despite --yes), functions new IDE prompts (flag-only yes, no piped read), db schema declarative generate/sync/ smart-target (flag-only yes, missing echo).
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5a430fcd4
ℹ️ 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".
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@4f241f0271c0386993e011cfdf5c793fa3589d8bPreview package for commit |
…e to match godotenv.Load (review: #3656892831) Go's loadNestedEnv uses godotenv.Load, which never overwrites a key already present in the shell env — even one set to false, empty, or an unparsable value — so shell presence must suppress the project .env value entirely instead of OR-ing the two parsed booleans. Applies to both SUPABASE_YES and SUPABASE_EXPERIMENTAL resolvers; unit tests cover the full godotenv/viper truth table.
|
@codex review |
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
|
@codex review |
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
…4-honor-yessupabase_yes-and-go-prompt-semantics-consistently # Conflicts: # apps/cli/src/legacy/commands/bootstrap/bootstrap.handler.ts # apps/cli/src/legacy/commands/branches/create/create.handler.ts # apps/cli/src/legacy/commands/logout/logout.handler.ts # apps/cli/src/legacy/commands/projects/delete/delete.handler.ts # apps/cli/src/legacy/commands/secrets/unset/unset.handler.ts # apps/cli/src/shared/functions/deploy.ts
Routes every legacy-parity confirmation through the single Go-faithful helper
legacyPromptYesNo(Go'sPromptYesNo,apps/cli-go/internal/utils/console.go:38-107) and deletes the per-command shortcuts, so all three Go prompt properties hold everywhere:--yesORSUPABASE_YESauto-confirms (viperAutomaticEnv; project.envconsulted exactly where Go'sloadNestedEnvruns before the prompt).<label> [y/N] yto stderr (console.go:70-72) instead of being silent.y/nwins, and only empty/unparseable input falls back to the default (console.go:38-61,96-102).Fixes CLI-1974 — https://linear.app/supabase/issue/CLI-1974/honor-yessupabase-yes-and-go-prompt-semantics-consistently-across
⚖ Flagged decision: item 3 (non-TTY piped stdin) is IMPLEMENTED
The issue left it open whether to match Go's non-TTY piped-stdin reads; this PR takes the recommended option and implements them. Concretely, commands that previously hardcoded a non-TTY default now consume one stdin line per confirmation and honor it:
echo y | supabase projects delete <ref>now deletes (previously silently cancelled — verified against develop with a from-source differential smoke test).echo n | supabase secrets unsetnow declines (previously proceeded unconditionally).echo n | supabase branches create(git-branch auto-name) now cancels; empty stdin keeps Go's Yes default.< /dev/nullor pass--yes. Veto here if this should be documented-divergence instead — the infrastructure (Stdin.readLine) was already in place from db push/reset, so no architectural cost either way.Per-site changes
logoutlogout.go:16(N)--yesshort-circuited before the stderr echoprojects deletedelete.go:22(N)SUPABASE_YES); non-TTY hardcoded cancel, no piped read, no label echo; title now aqua like Gobranches create(auto-name)create.go:21(Y)--yes/env ignored entirely (blocked a TTY); no piped read; no echo; title now aquasecrets unsetunset.go:34(Y)bootstrapoverwritebootstrap.go:48(Y)--yes; non-TTY went through clackfunctions deploy --prunedeploy.go:190(N)confirmPruneAll(•+ bold + trailing blank line, both shells)init -iIDE promptsinit.go:63,68(Y/N)--yes;--yesnow also lifts the stdout-TTY gate (Go only requires stdin TTY)functions newIDE promptsnew.go:99→init.go:62db schema declarative generate/sync/smart-targetdb_schema_declarative.go:269,321,381+declarative.go:234(N/N/Y/N)loadNestedEnv→ nowlegacyResolveYesWithProjectEnv); no echo under yes. The sync apply-decision (:452-460) and post-fail reset gate (:478) were already faithful 1:1 ports of Go's own short-circuits and are unchangedAlready-correct sites (unchanged): config push, db pull, db push ×3, db reset, gen signing-key, storage rm, seed buckets ×3 (via the helper), migration fetch/down/repair (via
legacyMigrationConfirm).Mechanics
legacyPromptYesNo+legacyParseYesNomoved fromsrc/legacy/shared/tosrc/shared/legacy/(same home aslegacyResolveYesinglobal-flags.ts) because two shared files (shared/functions/deploy.ts,shared/init/project-init.ts) now confirm through it. Semantics unchanged; importers updated path-only.ProjectInitOptionsgainsyes(legacy init passeslegacyResolveYes; next init passesfalse— next exposes no--yeson init, so next behavior is unchanged; bootstrap passes its resolved yes withinteractive: false).stdinLayeradded to the layer composition of every command whose confirmation can now read stdin; verified in the real composition by from-source smoke tests (piped y/n/--yes/SUPABASE_YESdifferentials vs develop).migration.prompt.tsnow reuses the sharedlegacyParseYesNoand both helpers cross-reference why they intentionally diverge (see below).Judgement calls deliberately left open (reviewer input welcome)
--output-format json|stream-json) without--yes:legacyPromptYesNokeeps its pre-existing contract — never prompt, silently take the call site's Go default. Routing more sites through it changes a few narrow machine-mode cells:secrets unsetjson+TTY now proceeds (default Y) instead of cancelling;bootstrapoverwrite json now proceeds instead of failing with a prompt error;declarative generate --localjson with existing files now skips (exit 0) instead of erroring. Go has no json mode; its script-mode analog (non-TTY) is exactly this default-through behavior, and this matches the helper's 7 pre-existing users (config push, db pull/push/reset, storage rm, signing-key, seed buckets).logoutdeliberately keeps its documented fail-loud json contract. A stricter "fail loudly in machine mode when the default is destructive" rule was proposed in internal review — it would change already-shipped behavior of the pre-existing helper users, so it is left as a follow-up decision. New regression test locks thesecrets unsetjson contract either way.legacyMigrationConfirmnot consolidated: the migration family's helper intentionally prompts regardless of output format and uses a raw TTY read (both arguably more Go-faithful); merging the two requires deciding the machine-mode question above first. Both files now carry cross-referencing comments so the divergence is explicit.shared/functions/deploy.ts→legacy/shared/legacy-colors.tsimport (for the bold prune slugs) deepens a pre-existing shared→legacy edge in that file (spawnContainerCli,legacy-docker-registryalready do this); hoisting the color primitives is left as a cleanup follow-up.functions deploy --pruneinherits Go's exact prompt bytes (•bullets, bold slugs, stderr echo under--yes, piped-stdin reads) via the shared file — deliberate, covered by new next-shell tests.Expected overlap with #5946
#5946 (CLI-1973, open) replaces
"context canceled"literals withCONTEXT_CANCELED_MESSAGEand suppresses the--debughint on declined prompts, touching many of the same handlers (logout, projects delete, secrets unset, branches create, bootstrap, db push/reset, migration *, signing-key,shared/functions/deploy.ts,shared/output/*). This branch is based on develop without it and avoids rewriting those exact lines; expect small, mechanical merge overlap in import blocks and around the cancellation branches whichever lands second.