From 0cf0cf572d904dba87bfab295e9bdf744562dbd5 Mon Sep 17 00:00:00 2001 From: Taran Pelkey Date: Fri, 28 Aug 2026 19:19:50 -0500 Subject: [PATCH] flag: make Apply return an error and drop errorableFlag The Flag interface's Apply method silently ignored parsing errors from environment-variable defaults; callers that wanted errors had to implement the unexported errorableFlag interface, and flagSet type-asserted for it. Fold ApplyWithError into Apply so the Flag interface returns an error directly, and delete errorableFlag along with the type assertion. This is a breaking change for external Flag implementations, hence v2. --- app_test.go | 3 +- flag.go | 125 +++++++--------------------------------------------- 2 files changed, 18 insertions(+), 110 deletions(-) diff --git a/app_test.go b/app_test.go index 0da939c1a0..3d6fac9389 100644 --- a/app_test.go +++ b/app_test.go @@ -1592,8 +1592,9 @@ func (c *customBoolFlag) GetName() string { return c.Nombre } -func (c *customBoolFlag) Apply(set *flag.FlagSet) { +func (c *customBoolFlag) Apply(set *flag.FlagSet) error { set.String(c.Nombre, c.Nombre, "") + return nil } func TestCustomFlagsUnused(t *testing.T) { diff --git a/flag.go b/flag.go index 8547f5385d..04c553c3cf 100644 --- a/flag.go +++ b/flag.go @@ -58,30 +58,16 @@ func (f FlagsByName) Swap(i, j int) { type Flag interface { fmt.Stringer // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) + Apply(*flag.FlagSet) error GetName() string } -// errorableFlag is an interface that allows us to return errors during apply -// it allows flags defined in this library to return errors in a fashion backwards compatible -// TODO remove in v2 and modify the existing Flag interface to return errors -type errorableFlag interface { - Flag - - ApplyWithError(*flag.FlagSet) error -} - func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { set := flag.NewFlagSet(name, flag.ContinueOnError) for _, f := range flags { - // TODO remove in v2 when errorableFlag is removed - if ef, ok := f.(errorableFlag); ok { - if err := ef.ApplyWithError(set); err != nil { - return nil, err - } - } else { - f.Apply(set) + if err := f.Apply(set); err != nil { + return nil, err } } return set, nil @@ -103,14 +89,7 @@ type Generic interface { // Apply takes the flagset and calls Set on the generic flag with the value // provided by the user for parsing by the flag -// Ignores parsing errors -func (f GenericFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError takes the flagset and calls Set on the generic flag with the value -// provided by the user for parsing by the flag -func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error { +func (f GenericFlag) Apply(set *flag.FlagSet) error { val := f.Value if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { @@ -156,13 +135,7 @@ func (f *StringSlice) Get() interface{} { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringSliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { +func (f StringSliceFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -219,13 +192,7 @@ func (f *IntSlice) Get() interface{} { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntSliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { +func (f IntSliceFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -282,13 +249,7 @@ func (f *Int64Slice) Get() interface{} { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64SliceFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { +func (f Int64SliceFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -316,13 +277,7 @@ func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { +func (f BoolFlag) Apply(set *flag.FlagSet) error { val := false if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { @@ -356,13 +311,7 @@ func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f BoolTFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { +func (f BoolTFlag) Apply(set *flag.FlagSet) error { val := true if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { @@ -396,13 +345,7 @@ func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f StringFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { +func (f StringFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -425,13 +368,7 @@ func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f IntFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { +func (f IntFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -458,13 +395,7 @@ func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f Int64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { +func (f Int64Flag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -492,13 +423,7 @@ func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f UintFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { +func (f UintFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -526,13 +451,7 @@ func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f Uint64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { +func (f Uint64Flag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -560,13 +479,7 @@ func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f DurationFlag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { +func (f DurationFlag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar) @@ -594,13 +507,7 @@ func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { } // Apply populates the flag given the flag set and environment -// Ignores errors -func (f Float64Flag) Apply(set *flag.FlagSet) { - f.ApplyWithError(set) -} - -// ApplyWithError populates the flag given the flag set and environment -func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error { +func (f Float64Flag) Apply(set *flag.FlagSet) error { if f.EnvVar != "" { for _, envVar := range strings.Split(f.EnvVar, ",") { envVar = strings.TrimSpace(envVar)