cli: flagWasSet resolves aliases through the claimed table
fs.Visit reports the spelling the user typed, so the old primary-only match went false when -a was given — a loaded gun for the wizard call sites the moment kind or target ever gains an alias. Moves next to cliAliases so the table and its one consumer stay in one file.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 files changed,
+45
−12
deploy.go+0 −12flags.go+18 −0flags_test.go+27 −0
diff --git a/deploy.go b/deploy.go| index 6e5a9415d..341fc2d40 100644 |
| --- a/deploy.go |
| +++ b/deploy.go |
| @@ -374,18 +374,6 @@ func projectArtifact(dsrc, artifact string) (string, error) { |
| return resolved, nil |
| } |
| -// flagWasSet reports whether the user typed a flag — the wizard and the |
| -// saved deploy block must never override an explicit -kind or -target. |
| -func flagWasSet(fs *flag.FlagSet, name string) bool { |
| - set := false |
| - fs.Visit(func(f *flag.Flag) { |
| - if f.Name == name { |
| - set = true |
| - } |
| - }) |
| - return set |
| -} |
| - |
| // deployArtifactWizard is first-run zero-arg deploy's one real question: |
| // WHAT ships. A conventional site directory (public/, dist/, _site/) only |
| // ever pre-fills the prompt — the human confirms; detection never decides. |
diff --git a/flags.go b/flags.go| index 991c603bf..48e088599 100644 |
| --- a/flags.go |
| +++ b/flags.go |
| @@ -63,3 +63,21 @@ func versionFlag(fs *flag.FlagSet, usage string) *string { |
| } |
| return aliasedString(fs, "version", "", usage) |
| } |
| + |
| +// flagWasSet reports whether the user typed a flag, by its primary name |
| +// OR its short alias — the wizard and the saved deploy block must never |
| +// override an explicit choice. fs.Visit reports the spelling actually |
| +// typed (measured in the spec), so matching the primary alone would go |
| +// false when -a was given: a wizard that then re-prompts for a value |
| +// the user just named. alias is "" for unaliased names, and f.Name is |
| +// never "", so the extra compare is inert there. |
| +func flagWasSet(fs *flag.FlagSet, name string) bool { |
| + alias := cliAliases[name] |
| + set := false |
| + fs.Visit(func(f *flag.Flag) { |
| + if f.Name == name || f.Name == alias { |
| + set = true |
| + } |
| + }) |
| + return set |
| +} |
diff --git a/flags_test.go b/flags_test.go| index 5b236d697..29279fd6c 100644 |
| --- a/flags_test.go |
| +++ b/flags_test.go |
| @@ -79,3 +79,30 @@ func TestHelperDefaultUsage(t *testing.T) { |
| t.Fatalf("bespoke usage lost: %q", got) |
| } |
| } |
| + |
| +// fs.Visit reports the spelling actually typed, so asking about the |
| +// primary alone goes false when -a was given. flagWasSet must be true |
| +// for every spelling — the deploy wizard's call sites depend on it. |
| +func TestFlagWasSetSeesEverySpelling(t *testing.T) { |
| + for _, args := range [][]string{ |
| + {"-app", "blah"}, {"--app", "blah"}, {"-a", "blah"}, |
| + } { |
| + fs := quietFlagSet("t") |
| + appFlag(fs, "") |
| + if err := fs.Parse(args); err != nil { |
| + t.Fatal(err) |
| + } |
| + if !flagWasSet(fs, "app") { |
| + t.Errorf("%v: flagWasSet(app) = false", args) |
| + } |
| + } |
| + fs := quietFlagSet("t") |
| + appFlag(fs, "") |
| + fs.String("kind", "", "artifact kind") |
| + if err := fs.Parse([]string{"-a", "blah"}); err != nil { |
| + t.Fatal(err) |
| + } |
| + if flagWasSet(fs, "kind") { |
| + t.Error("kind reported set when only -a was typed") |
| + } |
| +} |