Fix:(issue_1500). Fix slice flag value duplication issue
This commit is contained in:
parent
ea2893084b
commit
924ebdaab2
31
app_test.go
31
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"))
|
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) {
|
func TestApp_Float64Flag(t *testing.T) {
|
||||||
var meters float64
|
var meters float64
|
||||||
|
|
||||||
|
27
flag.go
27
flag.go
@ -126,6 +126,21 @@ type Flag interface {
|
|||||||
RunAction(*Context) error
|
RunAction(*Context) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DocGenerationFlag is an interface that allows documentation generation for the flag
|
||||||
|
type DocGenerationFlag interface {
|
||||||
|
Flag
|
||||||
|
|
||||||
|
// TakesValue returns true if the flag takes a value, otherwise false
|
||||||
|
TakesValue() bool
|
||||||
|
|
||||||
|
// GetValue returns the flags value as string representation and an empty
|
||||||
|
// string if the flag takes no value at all.
|
||||||
|
GetValue() string
|
||||||
|
|
||||||
|
// GetEnvVars returns the env vars for this flag
|
||||||
|
GetEnvVars() []string
|
||||||
|
}
|
||||||
|
|
||||||
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||||
type DocGenerationSliceFlag interface {
|
type DocGenerationSliceFlag interface {
|
||||||
DocGenerationFlag
|
DocGenerationFlag
|
||||||
@ -293,8 +308,14 @@ func formatDefault(format string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stringifyFlag(f Flag) string {
|
func stringifyFlag(f Flag) string {
|
||||||
placeholder, usage := unquoteUsage(f.GetUsage())
|
// enforce DocGeneration interface on flags to avoid reflection
|
||||||
needsPlaceholder := f.TakesValue()
|
df, ok := f.(DocGenerationFlag)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||||
|
needsPlaceholder := df.TakesValue()
|
||||||
|
|
||||||
if needsPlaceholder && placeholder == "" {
|
if needsPlaceholder && placeholder == "" {
|
||||||
placeholder = defaultPlaceholder
|
placeholder = defaultPlaceholder
|
||||||
@ -302,7 +323,7 @@ func stringifyFlag(f Flag) string {
|
|||||||
|
|
||||||
defaultValueString := ""
|
defaultValueString := ""
|
||||||
|
|
||||||
if s := f.GetDefaultText(); s != "" {
|
if s := df.GetDefaultText(); s != "" {
|
||||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
parse.go
5
parse.go
@ -46,7 +46,10 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
|
|||||||
}
|
}
|
||||||
|
|
||||||
// swap current argument with the split version
|
// 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
|
argsWereSplit = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user