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) {
|
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||||
switch ff.Value.(type) {
|
switch ff.Value.(type) {
|
||||||
case *StringSlice:
|
case Serializeder:
|
||||||
|
set.Set(name, ff.Value.(Serializeder).Serialized())
|
||||||
default:
|
default:
|
||||||
set.Set(name, ff.Value.String())
|
set.Set(name, ff.Value.String())
|
||||||
}
|
}
|
||||||
|
30
flag.go
30
flag.go
@ -1,6 +1,7 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -10,6 +11,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slPfx = fmt.Sprintf("sl:::%d:::", time.Now().UTC().UnixNano())
|
||||||
|
)
|
||||||
|
|
||||||
// This flag enables bash-completion for all commands and subcommands
|
// This flag enables bash-completion for all commands and subcommands
|
||||||
var BashCompletionFlag = BoolFlag{
|
var BashCompletionFlag = BoolFlag{
|
||||||
Name: "generate-bash-completion",
|
Name: "generate-bash-completion",
|
||||||
@ -29,6 +34,11 @@ var HelpFlag = BoolFlag{
|
|||||||
Usage: "show help",
|
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.
|
// Flag is a common interface related to parsing flags in cli.
|
||||||
// For more advanced flag parsing techniques, it is recommended that
|
// For more advanced flag parsing techniques, it is recommended that
|
||||||
// this interface be implemented.
|
// this interface be implemented.
|
||||||
@ -130,6 +140,13 @@ func (f *StringSlice) Set(value string) error {
|
|||||||
f.hasBeenSet = true
|
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)
|
f.slice = append(f.slice, value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -139,6 +156,12 @@ func (f *StringSlice) String() string {
|
|||||||
return fmt.Sprintf("%s", f.slice)
|
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
|
// Value returns the slice of strings set by this flag
|
||||||
func (f *StringSlice) Value() []string {
|
func (f *StringSlice) Value() []string {
|
||||||
return f.slice
|
return f.slice
|
||||||
@ -219,6 +242,13 @@ func (i *IntSlice) Set(value string) error {
|
|||||||
i.hasBeenSet = true
|
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)
|
tmp, err := strconv.Atoi(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
Loading…
Reference in New Issue
Block a user