From 55f2a9acf60173d56e4c8497d849fff748906f26 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 11 Aug 2022 15:49:12 -0500 Subject: [PATCH 1/9] adding in boolean alias support --- altsrc/flag.go | 21 +++++++++++++-------- altsrc/flag_test.go | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index db959493bc..21ddccf5ef 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -121,20 +121,25 @@ func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC // ApplyInputSourceValue applies a Bool value to the flagSet if required func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.isSet(f.BoolFlag.Name) { - value, err := isc.Bool(f.BoolFlag.Name) - if err != nil { - return err - } - if value { - for _, name := range f.Names() { - _ = f.set.Set(name, strconv.FormatBool(value)) + if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars){ + for _,name := range f.BoolFlag.Names(){ + if isc.isSet(name) { + value, err := isc.Bool(name) + if err != nil { + return err + } + if value { + for _, n := range f.Names() { + _ = f.set.Set(n, strconv.FormatBool(value)) + } + } } } } return nil } + // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.StringFlag.Name) { diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index e3725f7d1c..6916ea32d7 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -178,6 +178,20 @@ func TestBoolApplyInputSourceMethodSet(t *testing.T) { refute(t, true, c.Bool("test")) } +func TestBoolApplyInputSourceMethodSet_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewBoolFlag(&cli.BoolFlag{Name: "test",Aliases: []string{ "test_alias"}}), + FlagName: "test_alias", + MapValue: true, + } + c := runTest(t, tis) + expect(t, true, c.Bool("test_alias")) + + c = runRacyTest(t, tis) + refute(t, true, c.Bool("test_alias")) +} + + func TestBoolApplyInputSourceMethodContextSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}), From e767f7c7e48f3bb7f8ff7b8f741785f6be024ca2 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 11 Aug 2022 16:39:05 -0500 Subject: [PATCH 2/9] fixing formatting --- altsrc/flag.go | 5 ++--- altsrc/flag_test.go | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index 21ddccf5ef..daac809638 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -121,8 +121,8 @@ func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC // ApplyInputSourceValue applies a Bool value to the flagSet if required func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars){ - for _,name := range f.BoolFlag.Names(){ + if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { + for _, name := range f.BoolFlag.Names() { if isc.isSet(name) { value, err := isc.Bool(name) if err != nil { @@ -139,7 +139,6 @@ func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte return nil } - // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.StringFlag.Name) { diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index 6916ea32d7..d97c1848c2 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -180,7 +180,7 @@ func TestBoolApplyInputSourceMethodSet(t *testing.T) { func TestBoolApplyInputSourceMethodSet_Alias(t *testing.T) { tis := testApplyInputSource{ - Flag: NewBoolFlag(&cli.BoolFlag{Name: "test",Aliases: []string{ "test_alias"}}), + Flag: NewBoolFlag(&cli.BoolFlag{Name: "test", Aliases: []string{"test_alias"}}), FlagName: "test_alias", MapValue: true, } @@ -191,7 +191,6 @@ func TestBoolApplyInputSourceMethodSet_Alias(t *testing.T) { refute(t, true, c.Bool("test_alias")) } - func TestBoolApplyInputSourceMethodContextSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}), From a4c7af11bf089b06f54bbd026292139f83f85126 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 16:43:42 -0500 Subject: [PATCH 3/9] adding string alias and test --- altsrc/flag.go | 16 +++++++++------- altsrc/flag_test.go | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index dcdd28f831..f0138e58da 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -140,13 +140,15 @@ func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.StringFlag.Name) { - value, err := isc.String(f.StringFlag.Name) - if err != nil { - return err - } - if value != "" { - for _, name := range f.Names() { - _ = f.set.Set(name, value) + for _, name := range f.StringFlag.Names(){ + if isc.isSet(name) { + value, err := isc.String(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, value) + } } } } diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index d97c1848c2..47a280acfb 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -220,6 +220,20 @@ func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, true, c.Bool("test")) } +func TestStringApplyInputSourceMethodSet_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewStringFlag(&cli.StringFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test_alias", + MapValue: "hello", + ContextValueString: "goodbye", + } + c := runTest(t, tis) + expect(t, "goodbye", c.String("test_alias")) + + c = runRacyTest(t, tis) + refute(t, "goodbye", c.String("test_alias")) +} + func TestStringApplyInputSourceMethodSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewStringFlag(&cli.StringFlag{Name: "test"}), From b225dba032ce72f0a55de4966f61c03f76db41e1 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 16:48:26 -0500 Subject: [PATCH 4/9] adding int alias and test --- altsrc/flag.go | 16 ++++++++++------ altsrc/flag_test.go | 13 +++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index f0138e58da..095c4fa86b 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -184,12 +184,16 @@ func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a int value to the flagSet if required func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.IntFlag.Name) { - value, err := isc.Int(f.IntFlag.Name) - if err != nil { - return err - } - for _, name := range f.Names() { - _ = f.set.Set(name, strconv.FormatInt(int64(value), 10)) + for _, name := range f.IntFlag.Names() { + if isc.isSet(name) { + value, err := isc.Int(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, strconv.FormatInt(int64(value), 10)) + } + } } } return nil diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index 47a280acfb..6b92d7fdba 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -332,6 +332,19 @@ func TestPathApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, "goodbye", c.String("test")) } +func TestIntApplyInputSourceMethodSet_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewIntFlag(&cli.IntFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test", + MapValue: 15, + } + c := runTest(t, tis) + expect(t, 15, c.Int("test_alias")) + + c = runRacyTest(t, tis) + refute(t, 15, c.Int("test_alias")) +} + func TestIntApplyInputSourceMethodSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewIntFlag(&cli.IntFlag{Name: "test"}), From 4238aa199d5a572c721429669bb1b1e53d072667 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 16:53:29 -0500 Subject: [PATCH 5/9] add support for duration flag --- altsrc/flag.go | 16 ++++++++++------ altsrc/flag_test.go | 13 +++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index 095c4fa86b..e21b41d458 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -202,12 +202,16 @@ func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContex // ApplyInputSourceValue applies a Duration value to the flagSet if required func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.DurationFlag.Name) { - value, err := isc.Duration(f.DurationFlag.Name) - if err != nil { - return err - } - for _, name := range f.Names() { - _ = f.set.Set(name, value.String()) + for _, name := range f.DurationFlag.Names() { + if isc.isSet(name) { + value, err := isc.Duration(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, value.String()) + } + } } } return nil diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index 6b92d7fdba..43f26bd11e 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -400,6 +400,19 @@ func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, 12, c.Int("test")) } +func TestDurationApplyInputSourceMethodSet_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test", + MapValue: 30 * time.Second, + } + c := runTest(t, tis) + expect(t, 30*time.Second, c.Duration("test_alias")) + + c = runRacyTest(t, tis) + refute(t, 30*time.Second, c.Duration("test_alias")) +} + func TestDurationApplyInputSourceMethodSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}), From af5a5d530210e983cdc269d2f9c5017a372fe32c Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 16:59:57 -0500 Subject: [PATCH 6/9] adding float flag alias support --- altsrc/flag.go | 28 ++++++++++++++++------------ altsrc/flag_test.go | 13 +++++++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index e21b41d458..a0e38cc641 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -139,7 +139,7 @@ func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.StringFlag.Name) { + if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { for _, name := range f.StringFlag.Names(){ if isc.isSet(name) { value, err := isc.String(name) @@ -157,7 +157,7 @@ func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCon // ApplyInputSourceValue applies a Path value to the flagSet if required func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.PathFlag.Name) { + if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.String(f.PathFlag.Name) if err != nil { return err @@ -183,7 +183,7 @@ func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a int value to the flagSet if required func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.IntFlag.Name) { + if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { for _, name := range f.IntFlag.Names() { if isc.isSet(name) { value, err := isc.Int(name) @@ -201,7 +201,7 @@ func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContex // ApplyInputSourceValue applies a Duration value to the flagSet if required func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.DurationFlag.Name) { + if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { for _, name := range f.DurationFlag.Names() { if isc.isSet(name) { value, err := isc.Duration(name) @@ -219,14 +219,18 @@ func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC // ApplyInputSourceValue applies a Float64 value to the flagSet if required func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.isSet(f.Float64Flag.Name) { - value, err := isc.Float64(f.Float64Flag.Name) - if err != nil { - return err - } - floatStr := float64ToString(value) - for _, name := range f.Names() { - _ = f.set.Set(name, floatStr) + if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { + for _, name := range f.Float64Flag.Names() { + if isc.isSet(name) { + value, err := isc.Float64(name) + if err != nil { + return err + } + floatStr := float64ToString(value) + for _, n := range f.Names() { + _ = f.set.Set(n, floatStr) + } + } } } return nil diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index 43f26bd11e..bd6745ec32 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -481,6 +481,19 @@ func TestFloat64ApplyInputSourceMethodSet(t *testing.T) { refute(t, 1.3, c.Float64("test")) } +func TestFloat64ApplyInputSourceMethodSetNegativeValue_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test", + MapValue: -1.3, + } + c := runTest(t, tis) + expect(t, -1.3, c.Float64("test_alias")) + + c = runRacyTest(t, tis) + refute(t, -1.3, c.Float64("test_alias")) +} + func TestFloat64ApplyInputSourceMethodSetNegativeValue(t *testing.T) { tis := testApplyInputSource{ Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}), From 3280b9e5cf575694fdc92f8ee68c077c33f12789 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 17:17:01 -0500 Subject: [PATCH 7/9] adding alias support to remaining flags and fixing tests --- altsrc/flag.go | 104 +++++++++++++++++++++++++------------------- altsrc/flag_test.go | 71 ++++++++++++++++++++++++++++-- 2 files changed, 128 insertions(+), 47 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index a0e38cc641..48b4347010 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -64,14 +64,18 @@ func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *c // ApplyInputSourceValue applies a generic value to the flagSet if required func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.isSet(f.GenericFlag.Name) { - value, err := isc.Generic(f.GenericFlag.Name) - if err != nil { - return err - } - if value != nil { - for _, name := range f.Names() { - _ = f.set.Set(name, value.String()) + if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { + for _, name := range f.GenericFlag.Names() { + if isc.isSet(name) { + value, err := isc.Generic(name) + if err != nil { + return err + } + if value != nil { + for _, n := range f.Names() { + _ = f.set.Set(n, value.String()) + } + } } } } @@ -81,17 +85,21 @@ func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCo // ApplyInputSourceValue applies a StringSlice value to the flagSet if required func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.isSet(f.StringSliceFlag.Name) { - value, err := isc.StringSlice(f.StringSliceFlag.Name) - if err != nil { - return err - } - if value != nil { - var sliceValue cli.StringSlice = *(cli.NewStringSlice(value...)) - for _, name := range f.Names() { - underlyingFlag := f.set.Lookup(name) - if underlyingFlag != nil { - underlyingFlag.Value = &sliceValue + if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars){ + for _, name := range f.StringSliceFlag.Names() { + if isc.isSet(name) { + value, err := isc.StringSlice(name) + if err != nil { + return err + } + if value != nil { + var sliceValue = *(cli.NewStringSlice(value...)) + for _, n := range f.Names() { + underlyingFlag := f.set.Lookup(n) + if underlyingFlag != nil { + underlyingFlag.Value = &sliceValue + } + } } } } @@ -101,17 +109,21 @@ func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSour // ApplyInputSourceValue applies a IntSlice value if required func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.isSet(f.IntSliceFlag.Name) { - value, err := isc.IntSlice(f.IntSliceFlag.Name) - if err != nil { - return err - } - if value != nil { - var sliceValue cli.IntSlice = *(cli.NewIntSlice(value...)) - for _, name := range f.Names() { - underlyingFlag := f.set.Lookup(name) - if underlyingFlag != nil { - underlyingFlag.Value = &sliceValue + if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { + for _, name := range f.IntSliceFlag.Names() { + if isc.isSet(name) { + value, err := isc.IntSlice(name) + if err != nil { + return err + } + if value != nil { + var sliceValue = *(cli.NewIntSlice(value...)) + for _, n := range f.Names() { + underlyingFlag := f.set.Lookup(n) + if underlyingFlag != nil { + underlyingFlag.Value = &sliceValue + } + } } } } @@ -158,23 +170,27 @@ func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCon // ApplyInputSourceValue applies a Path value to the flagSet if required func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - value, err := isc.String(f.PathFlag.Name) - if err != nil { - return err - } - if value != "" { - for _, name := range f.Names() { + for _, name := range f.PathFlag.Names() { + if isc.isSet(name) { + value, err := isc.String(name) + if err != nil { + return err + } + if value != "" { + for _, n := range f.Names() { - if !filepath.IsAbs(value) && isc.Source() != "" { - basePathAbs, err := filepath.Abs(isc.Source()) - if err != nil { - return err - } + if !filepath.IsAbs(value) && isc.Source() != "" { + basePathAbs, err := filepath.Abs(isc.Source()) + if err != nil { + return err + } - value = filepath.Join(filepath.Dir(basePathAbs), value) - } + value = filepath.Join(filepath.Dir(basePathAbs), value) + } - _ = f.set.Set(name, value) + _ = f.set.Set(n, value) + } + } } } } diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index bd6745ec32..55105f022a 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -37,6 +37,20 @@ func (ris *racyInputSource) isSet(name string) bool { return true } +func TestGenericApplyInputSourceValue_Alias(t *testing.T) { + v := &Parser{"abc", "def"} + tis := testApplyInputSource{ + Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Aliases: []string{"test_alias"}, Value: &Parser{}}), + FlagName: "test_alias", + MapValue: v, + } + c := runTest(t, tis) + expect(t, v, c.Generic("test_alias")) + + c = runRacyTest(t, tis) + refute(t, v, c.Generic("test_alias")) +} + func TestGenericApplyInputSourceValue(t *testing.T) { v := &Parser{"abc", "def"} tis := testApplyInputSource{ @@ -85,6 +99,19 @@ func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, &Parser{"abc", "def"}, c.Generic("test")) } +func TestStringSliceApplyInputSourceValue_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test_alias", + MapValue: []interface{}{"hello", "world"}, + } + c := runTest(t, tis) + expect(t, c.StringSlice("test_alias"), []string{"hello", "world"}) + + c = runRacyTest(t, tis) + refute(t, c.StringSlice("test_alias"), []string{"hello", "world"}) +} + func TestStringSliceApplyInputSourceValue(t *testing.T) { tis := testApplyInputSource{ Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test"}), @@ -123,6 +150,19 @@ func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, c.StringSlice("test"), []string{"oh", "no"}) } +func TestIntSliceApplyInputSourceValue_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test_alias", + MapValue: []interface{}{1, 2}, + } + c := runTest(t, tis) + expect(t, c.IntSlice("test_alias"), []int{1, 2}) + + c = runRacyTest(t, tis) + refute(t, c.IntSlice("test_alias"), []int{1, 2}) +} + func TestIntSliceApplyInputSourceValue(t *testing.T) { tis := testApplyInputSource{ Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test"}), @@ -276,6 +316,31 @@ func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) { refute(t, "goodbye", c.String("test")) } +func TestPathApplyInputSourceMethodSet_Alias(t *testing.T) { + tis := testApplyInputSource{ + Flag: NewPathFlag(&cli.PathFlag{Name: "test", Aliases: []string{"test_alias"}}), + FlagName: "test_alias", + MapValue: "hello", + SourcePath: "/path/to/source/file", + } + c := runTest(t, tis) + + expected := "/path/to/source/hello" + if runtime.GOOS == "windows" { + var err error + // Prepend the corresponding drive letter (or UNC path?), and change + // to windows-style path: + expected, err = filepath.Abs(expected) + if err != nil { + t.Fatal(err) + } + } + expect(t, expected, c.String("test_alias")) + + c = runRacyTest(t, tis) + refute(t, expected, c.String("test_alias")) +} + func TestPathApplyInputSourceMethodSet(t *testing.T) { tis := testApplyInputSource{ Flag: NewPathFlag(&cli.PathFlag{Name: "test"}), @@ -335,7 +400,7 @@ func TestPathApplyInputSourceMethodEnvVarSet(t *testing.T) { func TestIntApplyInputSourceMethodSet_Alias(t *testing.T) { tis := testApplyInputSource{ Flag: NewIntFlag(&cli.IntFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test", + FlagName: "test_alias", MapValue: 15, } c := runTest(t, tis) @@ -403,7 +468,7 @@ func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) { func TestDurationApplyInputSourceMethodSet_Alias(t *testing.T) { tis := testApplyInputSource{ Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test", + FlagName: "test_alias", MapValue: 30 * time.Second, } c := runTest(t, tis) @@ -484,7 +549,7 @@ func TestFloat64ApplyInputSourceMethodSet(t *testing.T) { func TestFloat64ApplyInputSourceMethodSetNegativeValue_Alias(t *testing.T) { tis := testApplyInputSource{ Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test", + FlagName: "test_alias", MapValue: -1.3, } c := runTest(t, tis) From 9c02a7a2cf77acf71d465cd9c6439043ff8ee51d Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 17:18:51 -0500 Subject: [PATCH 8/9] fixing test --- altsrc/flag_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index 55105f022a..bece6aaf6c 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -265,13 +265,12 @@ func TestStringApplyInputSourceMethodSet_Alias(t *testing.T) { Flag: NewStringFlag(&cli.StringFlag{Name: "test", Aliases: []string{"test_alias"}}), FlagName: "test_alias", MapValue: "hello", - ContextValueString: "goodbye", } c := runTest(t, tis) - expect(t, "goodbye", c.String("test_alias")) + expect(t, "hello", c.String("test_alias")) c = runRacyTest(t, tis) - refute(t, "goodbye", c.String("test_alias")) + refute(t, "hello", c.String("test_alias")) } func TestStringApplyInputSourceMethodSet(t *testing.T) { From 843599ac4954a036ef2b6a54eb9dbd35bcde8604 Mon Sep 17 00:00:00 2001 From: Dokiy Date: Tue, 30 Aug 2022 14:29:39 +0800 Subject: [PATCH 9/9] Modify nesting flag apply --- altsrc/flag.go | 261 ++++++++++++++++++++++++++----------------------- 1 file changed, 141 insertions(+), 120 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index 48b4347010..1132ded35f 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -64,19 +64,22 @@ func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *c // ApplyInputSourceValue applies a generic value to the flagSet if required func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { - for _, name := range f.GenericFlag.Names() { - if isc.isSet(name) { - value, err := isc.Generic(name) - if err != nil { - return err - } - if value != nil { - for _, n := range f.Names() { - _ = f.set.Set(n, value.String()) - } - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.GenericFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.Generic(name) + if err != nil { + return err + } + if value == nil { + continue + } + for _, n := range f.Names() { + _ = f.set.Set(n, value.String()) } } @@ -85,23 +88,27 @@ func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCo // ApplyInputSourceValue applies a StringSlice value to the flagSet if required func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars){ - for _, name := range f.StringSliceFlag.Names() { - if isc.isSet(name) { - value, err := isc.StringSlice(name) - if err != nil { - return err - } - if value != nil { - var sliceValue = *(cli.NewStringSlice(value...)) - for _, n := range f.Names() { - underlyingFlag := f.set.Lookup(n) - if underlyingFlag != nil { - underlyingFlag.Value = &sliceValue - } - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.StringSliceFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.StringSlice(name) + if err != nil { + return err + } + if value == nil { + continue + } + var sliceValue = *(cli.NewStringSlice(value...)) + for _, n := range f.Names() { + underlyingFlag := f.set.Lookup(n) + if underlyingFlag == nil { + continue } + underlyingFlag.Value = &sliceValue } } return nil @@ -109,23 +116,27 @@ func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSour // ApplyInputSourceValue applies a IntSlice value if required func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { - for _, name := range f.IntSliceFlag.Names() { - if isc.isSet(name) { - value, err := isc.IntSlice(name) - if err != nil { - return err - } - if value != nil { - var sliceValue = *(cli.NewIntSlice(value...)) - for _, n := range f.Names() { - underlyingFlag := f.set.Lookup(n) - if underlyingFlag != nil { - underlyingFlag.Value = &sliceValue - } - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.IntSliceFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.IntSlice(name) + if err != nil { + return err + } + if value == nil { + continue + } + var sliceValue = *(cli.NewIntSlice(value...)) + for _, n := range f.Names() { + underlyingFlag := f.set.Lookup(n) + if underlyingFlag == nil { + continue } + underlyingFlag.Value = &sliceValue } } return nil @@ -133,17 +144,19 @@ func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC // ApplyInputSourceValue applies a Bool value to the flagSet if required func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { - for _, name := range f.BoolFlag.Names() { - if isc.isSet(name) { - value, err := isc.Bool(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, strconv.FormatBool(value)) - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.BoolFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.Bool(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, strconv.FormatBool(value)) } } return nil @@ -151,17 +164,19 @@ func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - for _, name := range f.StringFlag.Names(){ - if isc.isSet(name) { - value, err := isc.String(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, value) - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.StringFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.String(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, value) } } return nil @@ -169,29 +184,29 @@ func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCon // ApplyInputSourceValue applies a Path value to the flagSet if required func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - for _, name := range f.PathFlag.Names() { - if isc.isSet(name) { - value, err := isc.String(name) + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.PathFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.String(name) + if err != nil { + return err + } + if value == "" { + continue + } + for _, n := range f.Names() { + if !filepath.IsAbs(value) && isc.Source() != "" { + basePathAbs, err := filepath.Abs(isc.Source()) if err != nil { return err } - if value != "" { - for _, n := range f.Names() { - - if !filepath.IsAbs(value) && isc.Source() != "" { - basePathAbs, err := filepath.Abs(isc.Source()) - if err != nil { - return err - } - - value = filepath.Join(filepath.Dir(basePathAbs), value) - } - - _ = f.set.Set(n, value) - } - } + value = filepath.Join(filepath.Dir(basePathAbs), value) } + _ = f.set.Set(n, value) } } return nil @@ -199,17 +214,19 @@ func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte // ApplyInputSourceValue applies a int value to the flagSet if required func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - for _, name := range f.IntFlag.Names() { - if isc.isSet(name) { - value, err := isc.Int(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, strconv.FormatInt(int64(value), 10)) - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.IntFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.Int(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, strconv.FormatInt(int64(value), 10)) } } return nil @@ -217,17 +234,19 @@ func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContex // ApplyInputSourceValue applies a Duration value to the flagSet if required func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - for _, name := range f.DurationFlag.Names() { - if isc.isSet(name) { - value, err := isc.Duration(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, value.String()) - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.DurationFlag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.Duration(name) + if err != nil { + return err + } + for _, n := range f.Names() { + _ = f.set.Set(n, value.String()) } } return nil @@ -235,18 +254,20 @@ func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC // ApplyInputSourceValue applies a Float64 value to the flagSet if required func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { - for _, name := range f.Float64Flag.Names() { - if isc.isSet(name) { - value, err := isc.Float64(name) - if err != nil { - return err - } - floatStr := float64ToString(value) - for _, n := range f.Names() { - _ = f.set.Set(n, floatStr) - } - } + if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { + return nil + } + for _, name := range f.Float64Flag.Names() { + if !isc.isSet(name) { + continue + } + value, err := isc.Float64(name) + if err != nil { + return err + } + floatStr := float64ToString(value) + for _, n := range f.Names() { + _ = f.set.Set(n, floatStr) } } return nil