From ad539096814a3027d520b5401c36193a61e7f67e Mon Sep 17 00:00:00 2001 From: Naveen Gogineni Date: Thu, 18 Aug 2022 21:20:48 -0400 Subject: [PATCH] Fix:(issue_1272) Generic flag not set from env --- flag_bool.go | 7 ++++++- flag_generic.go | 2 +- flag_test.go | 18 +++++++++++------- godoc-current.txt | 28 ++++++++++++++-------------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/flag_bool.go b/flag_bool.go index b21d5163c9..3e19bde5b2 100644 --- a/flag_bool.go +++ b/flag_bool.go @@ -51,8 +51,13 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error { } f.Value = valBool - f.HasBeenSet = true + } else { + // empty value implies that the env is defined but set to empty string, we have to assume that this is + // what the user wants. If user doesnt want this then the env needs to be deleted or the flag removed from + // file + f.Value = false } + f.HasBeenSet = true } for _, name := range f.Names() { diff --git a/flag_generic.go b/flag_generic.go index 680eeb9d71..6a19aef36c 100644 --- a/flag_generic.go +++ b/flag_generic.go @@ -50,7 +50,7 @@ func (f *GenericFlag) GetEnvVars() []string { // Apply 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) Apply(set *flag.FlagSet) error { +func (f *GenericFlag) Apply(set *flag.FlagSet) error { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { if err := f.Value.Set(val); err != nil { diff --git a/flag_test.go b/flag_test.go index d3ded729bb..ad500f12d9 100644 --- a/flag_test.go +++ b/flag_test.go @@ -157,6 +157,10 @@ func TestFlagsFromEnv(t *testing.T) { if !reflect.DeepEqual(ctx.Value(test.flag.Names()[0]), test.output) { t.Errorf("ex:%01d expected %q to be parsed as %#v, instead was %#v", i, test.input, test.output, ctx.Value(test.flag.Names()[0])) } + if !f.IsSet() { + t.Errorf("Flag %s not set", f.Names()[0]) + } + return nil }, } @@ -2398,43 +2402,43 @@ func TestFlagDefaultValue(t *testing.T) { name: "stringSclice", flag: &StringSliceFlag{Name: "flag", Value: NewStringSlice("default1", "default2")}, toParse: []string{"--flag", "parsed"}, - expect: `--flag value [ --flag value ] (default: "default1", "default2")`, + expect: `--flag value [ --flag value ] (default: "default1", "default2")`, }, { name: "float64Sclice", flag: &Float64SliceFlag{Name: "flag", Value: NewFloat64Slice(1.1, 2.2)}, toParse: []string{"--flag", "13.3"}, - expect: `--flag value [ --flag value ] (default: 1.1, 2.2)`, + expect: `--flag value [ --flag value ] (default: 1.1, 2.2)`, }, { name: "int64Sclice", flag: &Int64SliceFlag{Name: "flag", Value: NewInt64Slice(1, 2)}, toParse: []string{"--flag", "13"}, - expect: `--flag value [ --flag value ] (default: 1, 2)`, + expect: `--flag value [ --flag value ] (default: 1, 2)`, }, { name: "intSclice", flag: &IntSliceFlag{Name: "flag", Value: NewIntSlice(1, 2)}, toParse: []string{"--flag", "13"}, - expect: `--flag value [ --flag value ] (default: 1, 2)`, + expect: `--flag value [ --flag value ] (default: 1, 2)`, }, { name: "string", flag: &StringFlag{Name: "flag", Value: "default"}, toParse: []string{"--flag", "parsed"}, - expect: `--flag value (default: "default")`, + expect: `--flag value (default: "default")`, }, { name: "bool", flag: &BoolFlag{Name: "flag", Value: true}, toParse: []string{"--flag", "false"}, - expect: `--flag (default: true)`, + expect: `--flag (default: true)`, }, { name: "uint64", flag: &Uint64Flag{Name: "flag", Value: 1}, toParse: []string{"--flag", "13"}, - expect: `--flag value (default: 1)`, + expect: `--flag value (default: 1)`, }, } for i, v := range cases { diff --git a/godoc-current.txt b/godoc-current.txt index 6d0a908753..6d047da391 100644 --- a/godoc-current.txt +++ b/godoc-current.txt @@ -5,24 +5,24 @@ line Go applications. cli is designed to be easy to understand and write, the most simple cli application can be written as follows: func main() { - (&cli.App{}).Run(os.Args) + (&cli.App{}).Run(os.Args) } Of course this application does not do much, so let's make this an actual application: - func main() { - app := &cli.App{ - Name: "greet", - Usage: "say a greeting", - Action: func(c *cli.Context) error { - fmt.Println("Greetings") - return nil - }, - } - - app.Run(os.Args) - } + func main() { + app := &cli.App{ + Name: "greet", + Usage: "say a greeting", + Action: func(c *cli.Context) error { + fmt.Println("Greetings") + return nil + }, + } + + app.Run(os.Args) + } VARIABLES @@ -1073,7 +1073,7 @@ type GenericFlag struct { } GenericFlag is a flag with type Generic -func (f GenericFlag) Apply(set *flag.FlagSet) error +func (f *GenericFlag) Apply(set *flag.FlagSet) error Apply takes the flagset and calls Set on the generic flag with the value provided by the user for parsing by the flag