diff --git a/app_test.go b/app_test.go index d3fa3dfdad..62007188d0 100644 --- a/app_test.go +++ b/app_test.go @@ -956,6 +956,37 @@ func TestApp_UseShortOptionHandlingSubCommand_missing_value(t *testing.T) { expect(t, err, errors.New("flag needs an argument: -n")) } +func TestApp_UseShortOptionAfterSliceFlag(t *testing.T) { + var one, two bool + var name string + var sliceValDest StringSlice + var sliceVal []string + expected := "expectedName" + + app := newTestApp() + app.UseShortOptionHandling = true + app.Flags = []Flag{ + &StringSliceFlag{Name: "env", Aliases: []string{"e"}, Destination: &sliceValDest}, + &BoolFlag{Name: "one", Aliases: []string{"o"}}, + &BoolFlag{Name: "two", Aliases: []string{"t"}}, + &StringFlag{Name: "name", Aliases: []string{"n"}}, + } + app.Action = func(c *Context) error { + sliceVal = c.StringSlice("env") + one = c.Bool("one") + two = c.Bool("two") + name = c.String("name") + return nil + } + + _ = app.Run([]string{"", "-e", "foo", "-on", expected}) + expect(t, sliceVal, []string{"foo"}) + expect(t, sliceValDest.Value(), []string{"foo"}) + expect(t, one, true) + expect(t, two, false) + expect(t, name, expected) +} + func TestApp_Float64Flag(t *testing.T) { var meters float64 diff --git a/parse.go b/parse.go index a2db306e12..d79f15a18e 100644 --- a/parse.go +++ b/parse.go @@ -46,7 +46,10 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple } // swap current argument with the split version - args = append(args[:i], append(shortOpts, args[i+1:]...)...) + // do not include args that parsed correctly so far as it would + // trigger Value.Set() on those args and would result in + // duplicates for slice type flags + args = append(shortOpts, args[i+1:]...) argsWereSplit = true break } @@ -56,13 +59,6 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple if !argsWereSplit { return err } - - // Since custom parsing failed, replace the flag set before retrying - newSet, err := ip.newFlagSet() - if err != nil { - return err - } - *set = *newSet } }