From 9630e101c363925e8e5aaa777bcae2f15404c1e2 Mon Sep 17 00:00:00 2001 From: James He Date: Thu, 25 Aug 2022 17:17:01 -0500 Subject: [PATCH] adding alias support to remaining flags and fixing tests --- altsrc/flag.go | 106 +++++++++++++++++++++++++------------------- altsrc/flag_test.go | 71 +++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 48 deletions(-) diff --git a/altsrc/flag.go b/altsrc/flag.go index 37e9b03..1d3917e 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 + } + } } } } @@ -160,23 +172,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() { - - if !filepath.IsAbs(value) && isc.Source() != "" { - basePathAbs, err := filepath.Abs(isc.Source()) - if err != nil { - return err - } - - value = filepath.Join(filepath.Dir(basePathAbs), value) + 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() { - _ = f.set.Set(name, value) + 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) + } + } } } } diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index bd6745e..55105f0 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)