diff --git a/altsrc/flag.go b/altsrc/flag.go index 1132ded35f..8697b29d0a 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -110,6 +110,9 @@ func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSour } underlyingFlag.Value = &sliceValue } + if f.Destination != nil { + f.Destination.Set(sliceValue.Serialize()) + } } return nil } @@ -138,6 +141,9 @@ func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC } underlyingFlag.Value = &sliceValue } + if f.Destination != nil { + f.Destination.Set(sliceValue.Serialize()) + } } return nil } diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go index b2cbb52557..caf62d87f2 100644 --- a/altsrc/flag_test.go +++ b/altsrc/flag_test.go @@ -100,39 +100,61 @@ func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) { } func TestStringSliceApplyInputSourceValue_Alias(t *testing.T) { + dest := cli.NewStringSlice() tis := testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}}), + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), FlagName: "test_alias", MapValue: []interface{}{"hello", "world"}, } c := runTest(t, tis) expect(t, c.StringSlice("test_alias"), []string{"hello", "world"}) + expect(t, dest.Value(), []string{"hello", "world"}) + // reset dest + dest = cli.NewStringSlice() + tis = testApplyInputSource{ + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), + FlagName: "test_alias", + MapValue: []interface{}{"hello", "world"}, + } c = runRacyTest(t, tis) refute(t, c.StringSlice("test_alias"), []string{"hello", "world"}) + refute(t, dest.Value(), []string{"hello", "world"}) } func TestStringSliceApplyInputSourceValue(t *testing.T) { + dest := cli.NewStringSlice() tis := testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test"}), + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), FlagName: "test", MapValue: []interface{}{"hello", "world"}, } c := runTest(t, tis) expect(t, c.StringSlice("test"), []string{"hello", "world"}) + expect(t, dest.Value(), []string{"hello", "world"}) + // reset dest + dest = cli.NewStringSlice() + tis = testApplyInputSource{ + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), + FlagName: "test", + MapValue: []interface{}{"hello", "world"}, + } c = runRacyTest(t, tis) refute(t, c.StringSlice("test"), []string{"hello", "world"}) + refute(t, dest.Value(), []string{"hello", "world"}) } func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) { + dest := cli.NewStringSlice() c := runTest(t, testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test"}), + Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), FlagName: "test", MapValue: []interface{}{"hello", "world"}, ContextValueString: "ohno", }) expect(t, c.StringSlice("test"), []string{"ohno"}) + expect(t, dest.Value(), []string{"ohno"}) } func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { @@ -151,43 +173,73 @@ func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { } func TestIntSliceApplyInputSourceValue_Alias(t *testing.T) { + dest := cli.NewIntSlice() tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}}), + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), FlagName: "test_alias", MapValue: []interface{}{1, 2}, } c := runTest(t, tis) expect(t, c.IntSlice("test_alias"), []int{1, 2}) + expect(t, dest.Value(), []int{1, 2}) + dest = cli.NewIntSlice() + tis = testApplyInputSource{ + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), + FlagName: "test_alias", + MapValue: []interface{}{1, 2}, + } c = runRacyTest(t, tis) refute(t, c.IntSlice("test_alias"), []int{1, 2}) + refute(t, dest.Value(), []int{1, 2}) } func TestIntSliceApplyInputSourceValue(t *testing.T) { + dest := cli.NewIntSlice() tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test"}), + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), FlagName: "test", MapValue: []interface{}{1, 2}, } c := runTest(t, tis) expect(t, c.IntSlice("test"), []int{1, 2}) + expect(t, dest.Value(), []int{1, 2}) + // reset dest + dest = cli.NewIntSlice() + tis = testApplyInputSource{ + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), + FlagName: "test", + MapValue: []interface{}{1, 2}, + } c = runRacyTest(t, tis) refute(t, c.IntSlice("test"), []int{1, 2}) + refute(t, dest.Value(), []int{1, 2}) } func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) { + dest := cli.NewIntSlice() tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test"}), + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), FlagName: "test", MapValue: []interface{}{1, 2}, ContextValueString: "3", } c := runTest(t, tis) expect(t, c.IntSlice("test"), []int{3}) + expect(t, dest.Value(), []int{3}) + // reset dest + dest = cli.NewIntSlice() + tis = testApplyInputSource{ + Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), + FlagName: "test", + MapValue: []interface{}{1, 2}, + ContextValueString: "3", + } c = runRacyTest(t, tis) refute(t, c.IntSlice("test"), []int{3}) + refute(t, dest.Value(), []int{3}) } func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { diff --git a/altsrc/yaml_file_loader.go b/altsrc/yaml_file_loader.go index 315db1885f..62e8965782 100644 --- a/altsrc/yaml_file_loader.go +++ b/altsrc/yaml_file_loader.go @@ -33,11 +33,9 @@ func NewYamlSourceFromFile(file string) (InputSourceContext, error) { // NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context. func NewYamlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) { return func(cCtx *cli.Context) (InputSourceContext, error) { - if cCtx.IsSet(flagFileName) { - filePath := cCtx.String(flagFileName) + if filePath := cCtx.String(flagFileName); filePath != "" { return NewYamlSourceFromFile(filePath) } - return defaultInputSource() } }