Generic parsers as flag types
This commit is contained in:
parent
640826c88f
commit
13e88629f5
19
context.go
19
context.go
@ -58,6 +58,11 @@ func (c *Context) IntSlice(name string) []int {
|
|||||||
return lookupIntSlice(name, c.flagSet)
|
return lookupIntSlice(name, c.flagSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Looks up the value of a local generic flag, returns nil if no generic flag exists
|
||||||
|
func (c *Context) Generic(name string) interface{} {
|
||||||
|
return lookupGeneric(name, c.flagSet)
|
||||||
|
}
|
||||||
|
|
||||||
// Looks up the value of a global int flag, returns 0 if no int flag exists
|
// Looks up the value of a global int flag, returns 0 if no int flag exists
|
||||||
func (c *Context) GlobalInt(name string) int {
|
func (c *Context) GlobalInt(name string) int {
|
||||||
return lookupInt(name, c.globalSet)
|
return lookupInt(name, c.globalSet)
|
||||||
@ -83,6 +88,11 @@ func (c *Context) GlobalIntSlice(name string) []int {
|
|||||||
return lookupIntSlice(name, c.globalSet)
|
return lookupIntSlice(name, c.globalSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Looks up the value of a global generic flag, returns nil if no generic flag exists
|
||||||
|
func (c *Context) GlobalGeneric(name string) interface{} {
|
||||||
|
return lookupGeneric(name, c.globalSet)
|
||||||
|
}
|
||||||
|
|
||||||
// Determines if the flag was actually set exists
|
// Determines if the flag was actually set exists
|
||||||
func (c *Context) IsSet(name string) bool {
|
func (c *Context) IsSet(name string) bool {
|
||||||
if c.setFlags == nil {
|
if c.setFlags == nil {
|
||||||
@ -184,6 +194,14 @@ func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
||||||
|
f := set.Lookup(name)
|
||||||
|
if f != nil {
|
||||||
|
return (f.Value.(Generic)).Value()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
func lookupBool(name string, set *flag.FlagSet) bool {
|
||||||
f := set.Lookup(name)
|
f := set.Lookup(name)
|
||||||
if f != nil {
|
if f != nil {
|
||||||
@ -197,7 +215,6 @@ func lookupBool(name string, set *flag.FlagSet) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func lookupBoolT(name string, set *flag.FlagSet) bool {
|
func lookupBoolT(name string, set *flag.FlagSet) bool {
|
||||||
f := set.Lookup(name)
|
f := set.Lookup(name)
|
||||||
if f != nil {
|
if f != nil {
|
||||||
|
28
flag.go
28
flag.go
@ -37,6 +37,34 @@ func eachName(longName string, fn func(string)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generic is a generic parseable type identified by a specific flag
|
||||||
|
type Generic interface {
|
||||||
|
Set(value string) error
|
||||||
|
String() string
|
||||||
|
Value() interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenericFlag is the flag type for types implementing Generic
|
||||||
|
type GenericFlag struct {
|
||||||
|
Name string
|
||||||
|
Value Generic
|
||||||
|
Usage string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f GenericFlag) String() string {
|
||||||
|
return fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f GenericFlag) Apply(set *flag.FlagSet) {
|
||||||
|
eachName(f.Name, func(name string) {
|
||||||
|
set.Var(f.Value, name, f.Usage)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f GenericFlag) getName() string {
|
||||||
|
return f.Name
|
||||||
|
}
|
||||||
|
|
||||||
type StringSlice []string
|
type StringSlice []string
|
||||||
|
|
||||||
func (f *StringSlice) Set(value string) error {
|
func (f *StringSlice) Set(value string) error {
|
||||||
|
42
flag_test.go
42
flag_test.go
@ -2,7 +2,10 @@ package cli_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/codegangsta/cli"
|
"github.com/codegangsta/cli"
|
||||||
|
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -154,3 +157,42 @@ func TestParseMultiBool(t *testing.T) {
|
|||||||
}
|
}
|
||||||
a.Run([]string{"run", "--serve"})
|
a.Run([]string{"run", "--serve"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Parser [2]string
|
||||||
|
|
||||||
|
func (p *Parser) Set(value string) error {
|
||||||
|
parts := strings.Split(value, ",")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return fmt.Errorf("invalid format")
|
||||||
|
}
|
||||||
|
|
||||||
|
(*p)[0] = parts[0]
|
||||||
|
(*p)[1] = parts[1]
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) String() string {
|
||||||
|
return fmt.Sprintf("%s,%s", p[0], p[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Parser) Value() interface{} {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseGeneric(t *testing.T) {
|
||||||
|
a := cli.App{
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.GenericFlag{Name: "serve, s", Value: &Parser{}},
|
||||||
|
},
|
||||||
|
Action: func(ctx *cli.Context) {
|
||||||
|
if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) {
|
||||||
|
t.Errorf("main name not set")
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) {
|
||||||
|
t.Errorf("short name not set")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
a.Run([]string{"run", "-s", "10,20"})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user