Merge pull request #81 from zenoss/upstream/feature/generic-flags

Generic parsers as flag types
main
Jeremy Saenz 10 years ago
commit bb9189510a

@ -59,6 +59,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)
@ -84,6 +89,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 {
@ -185,6 +195,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
}
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 {
@ -198,7 +216,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 {

@ -43,6 +43,33 @@ 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
}
// 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 {

@ -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,38 @@ 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 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…
Cancel
Save