Ensure slice types can safely round-trip through flag.FlagSet
This commit is contained in:
parent
ee736e063a
commit
d1b0c49a98
@ -362,7 +362,8 @@ func lookupBoolT(name string, set *flag.FlagSet) bool {
|
||||
|
||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||
switch ff.Value.(type) {
|
||||
case *StringSlice:
|
||||
case Serializeder:
|
||||
set.Set(name, ff.Value.(Serializeder).Serialized())
|
||||
default:
|
||||
set.Set(name, ff.Value.String())
|
||||
}
|
||||
|
30
flag.go
30
flag.go
@ -1,6 +1,7 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -10,6 +11,10 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||
)
|
||||
|
||||
// This flag enables bash-completion for all commands and subcommands
|
||||
var BashCompletionFlag = BoolFlag{
|
||||
Name: "generate-bash-completion",
|
||||
@ -29,6 +34,11 @@ var HelpFlag = BoolFlag{
|
||||
Usage: "show help",
|
||||
}
|
||||
|
||||
// Serializeder is used to circumvent the limitations of flag.FlagSet.Set
|
||||
type Serializeder interface {
|
||||
Serialized() string
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
@ -130,6 +140,13 @@ func (f *StringSlice) Set(value string) error {
|
||||
f.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
v := []string{}
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), v)
|
||||
f.slice = append(f.slice, v...)
|
||||
return nil
|
||||
}
|
||||
|
||||
f.slice = append(f.slice, value)
|
||||
return nil
|
||||
}
|
||||
@ -139,6 +156,12 @@ func (f *StringSlice) String() string {
|
||||
return fmt.Sprintf("%s", f.slice)
|
||||
}
|
||||
|
||||
// Serialized allows StringSlice to fulfill Serializeder
|
||||
func (f *StringSlice) Serialized() string {
|
||||
jsonBytes, _ := json.Marshal(f.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of strings set by this flag
|
||||
func (f *StringSlice) Value() []string {
|
||||
return f.slice
|
||||
@ -219,6 +242,13 @@ func (i *IntSlice) Set(value string) error {
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(slPfx, value) {
|
||||
v := []int{}
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), v)
|
||||
i.slice = append(i.slice, v...)
|
||||
return nil
|
||||
}
|
||||
|
||||
tmp, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user