Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ func (f *FlagSet) Set(name, value string) error {
}

if flag.Deprecated != "" {
_, _ = fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
_, _ = fmt.Fprintf(f.Output(), "Flag --%s has been deprecated, %s\n", name, flag.Deprecated)
}
return nil
}
Expand Down Expand Up @@ -1110,7 +1110,9 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin
return
}

err = fn(flag, value)
// Pass the name the user actually typed so a deprecation message reports
// it rather than the canonical name a NormalizeFunc may have mapped it to.
err = fn(flag, name, value)
if err != nil {
err = f.fail(err)
}
Expand Down Expand Up @@ -1200,7 +1202,9 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parse
_, _ = fmt.Fprintf(f.Output(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
}

err = fn(flag, value)
// A shorthand has no alias to report, so a deprecation message keeps the
// canonical long name.
err = fn(flag, flag.Name, value)
if err != nil {
err = f.fail(err)
}
Expand Down Expand Up @@ -1294,8 +1298,8 @@ func (f *FlagSet) Parse(arguments []string) error {
return nil
}

set := func(flag *Flag, value string) error {
return f.Set(flag.Name, value)
set := func(flag *Flag, name, value string) error {
return f.Set(name, value)
}

err := f.parseArgs(arguments, set)
Expand All @@ -1316,7 +1320,7 @@ func (f *FlagSet) Parse(arguments []string) error {
return nil
}

type parseFunc func(flag *Flag, value string) error
type parseFunc func(flag *Flag, name, value string) error

// ParseAll parses flag definitions from the argument list, which should not
// include the command name. The arguments for fn are flag and value. Must be
Expand All @@ -1327,7 +1331,11 @@ func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string)
f.parsed = true
f.args = make([]string, 0, len(arguments))

err := f.parseArgs(arguments, fn)
set := func(flag *Flag, name, value string) error {
return fn(flag, value)
}

err := f.parseArgs(arguments, set)
if err != nil {
switch f.errorHandling {
case ContinueOnError:
Expand Down
27 changes: 27 additions & 0 deletions flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1401,6 +1401,33 @@ func TestDeprecatedFlagUsageNormalized(t *testing.T) {
}
}

func TestDeprecatedFlagUsageAlias(t *testing.T) {
// When a NormalizeFunc aliases one flag name to another, using the alias
// to set a deprecated flag should report the name the user actually typed,
// not the canonical name. See https://github.com/spf13/pflag/issues/279.
f := NewFlagSet("bob", ContinueOnError)
f.String("src", "", "src directory or file")
f.SetNormalizeFunc(func(_ *FlagSet, name string) NormalizedName {
if name == "dir" {
name = "src"
}
return NormalizedName(name)
})
_ = f.MarkDeprecated("src", "use --src")

out, err := parseReturnStderr(t, f, []string{"--dir=x"})
if err != nil {
t.Fatal("expected no error; got ", err)
}

if !strings.Contains(out, "Flag --dir has been deprecated") {
t.Errorf("expected the deprecation message to name the flag the user typed (--dir); got: %q", out)
}
if strings.Contains(out, "Flag --src has been deprecated") {
t.Errorf("deprecation message should not name the canonical flag (--src); got: %q", out)
}
}

// Name normalization function should be called only once on flag addition
func TestMultipleNormalizeFlagNameInvocations(t *testing.T) {
normalizeFlagNameInvocations = 0
Expand Down
Loading