Merge pull request #38 from thesyncim/master
add ability to parse []string types
This commit is contained in:
commit
3c97f95b6a
58
app_test.go
58
app_test.go
@ -84,3 +84,61 @@ func TestApp_CommandWithArgBeforeFlags(t *testing.T) {
|
||||
expect(t, parsedOption, "my-option")
|
||||
expect(t, firstArg, "my-arg")
|
||||
}
|
||||
|
||||
func TestApp_ParseSliceFlags(t *testing.T) {
|
||||
var parsedOption, firstArg string
|
||||
var parsedIntSlice []int
|
||||
var parsedStringSlice []string
|
||||
|
||||
app := cli.NewApp()
|
||||
command := cli.Command{
|
||||
Name: "cmd",
|
||||
Flags: []cli.Flag{
|
||||
cli.IntSliceFlag{"p", &cli.IntSlice{}, "set one or more ip addr"},
|
||||
cli.StringSliceFlag{"ip", &cli.StringSlice{}, "set one or more ports to open"},
|
||||
},
|
||||
Action: func(c *cli.Context) {
|
||||
parsedIntSlice = c.IntSlice("p")
|
||||
parsedStringSlice = c.StringSlice("ip")
|
||||
parsedOption = c.String("option")
|
||||
firstArg = c.Args()[0]
|
||||
},
|
||||
}
|
||||
app.Commands = []cli.Command{command}
|
||||
|
||||
app.Run([]string{"", "cmd", "my-arg", "-p", "22", "-p", "80", "-ip", "8.8.8.8", "-ip", "8.8.4.4"})
|
||||
|
||||
IntsEquals := func(a, b []int) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
StrsEquals := func(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
var expectedIntSlice = []int{22, 80}
|
||||
var expectedStringSlice = []string{"8.8.8.8", "8.8.4.4"}
|
||||
|
||||
if !IntsEquals(parsedIntSlice, expectedIntSlice) {
|
||||
t.Errorf("%s does not match %s", parsedIntSlice, expectedIntSlice)
|
||||
}
|
||||
|
||||
if !StrsEquals(parsedStringSlice, expectedStringSlice) {
|
||||
t.Errorf("%s does not match %s", parsedStringSlice, expectedStringSlice)
|
||||
}
|
||||
}
|
||||
|
15
command.go
15
command.go
@ -1,19 +1,19 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
Name string
|
||||
ShortName string
|
||||
Usage string
|
||||
Description string
|
||||
Action func (context *Context)
|
||||
Flags []Flag
|
||||
Name string
|
||||
ShortName string
|
||||
Usage string
|
||||
Description string
|
||||
Action func(context *Context)
|
||||
Flags []Flag
|
||||
}
|
||||
|
||||
func (c Command) Run(ctx *Context) {
|
||||
@ -52,7 +52,6 @@ func (c Command) Run(ctx *Context) {
|
||||
|
||||
context := NewContext(ctx.App, set, ctx.globalSet)
|
||||
checkCommandHelp(context, c.Name)
|
||||
|
||||
c.Action(context)
|
||||
}
|
||||
|
||||
|
40
context.go
40
context.go
@ -34,6 +34,16 @@ func (c *Context) String(name string) string {
|
||||
return c.lookupString(name, c.flagSet)
|
||||
}
|
||||
|
||||
// Looks up the value of a local string slice flag, returns nil if no string slice flag exists
|
||||
func (c *Context) StringSlice(name string) []string {
|
||||
return c.lookupStringSlice(name, c.flagSet)
|
||||
}
|
||||
|
||||
// Looks up the value of a local int slice flag, returns nil if no int slice flag exists
|
||||
func (c *Context) IntSlice(name string) []int {
|
||||
return c.lookupIntSlice(name, c.flagSet)
|
||||
}
|
||||
|
||||
// Looks up the value of a global int flag, returns 0 if no int flag exists
|
||||
func (c *Context) GlobalInt(name string) int {
|
||||
return c.lookupInt(name, c.globalSet)
|
||||
@ -49,6 +59,16 @@ func (c *Context) GlobalString(name string) string {
|
||||
return c.lookupString(name, c.globalSet)
|
||||
}
|
||||
|
||||
// Looks up the value of a global string slice flag, returns nil if no string slice flag exists
|
||||
func (c *Context) GlobalStringSlice(name string) []string {
|
||||
return c.lookupStringSlice(name, c.globalSet)
|
||||
}
|
||||
|
||||
// Looks up the value of a global int slice flag, returns nil if no int slice flag exists
|
||||
func (c *Context) GlobalIntSlice(name string) []int {
|
||||
return c.lookupIntSlice(name, c.globalSet)
|
||||
}
|
||||
|
||||
func (c *Context) Args() []string {
|
||||
return c.flagSet.Args()
|
||||
}
|
||||
@ -75,6 +95,26 @@ func (c *Context) lookupString(name string, set *flag.FlagSet) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (c *Context) lookupStringSlice(name string, set *flag.FlagSet) []string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
return (f.Value.(*StringSlice)).Value()
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) lookupIntSlice(name string, set *flag.FlagSet) []int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
return (f.Value.(*IntSlice)).Value()
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Context) lookupBool(name string, set *flag.FlagSet) bool {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
|
66
flag.go
66
flag.go
@ -2,6 +2,7 @@ package cli
|
||||
|
||||
import "fmt"
|
||||
import "flag"
|
||||
import "strconv"
|
||||
|
||||
type Flag interface {
|
||||
fmt.Stringer
|
||||
@ -10,12 +11,77 @@ type Flag interface {
|
||||
|
||||
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||
|
||||
for _, f := range flags {
|
||||
f.Apply(set)
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
type StringSlice []string
|
||||
|
||||
func (f *StringSlice) Set(value string) error {
|
||||
*f = append(*f, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *StringSlice) String() string {
|
||||
return fmt.Sprintf("%s", *f)
|
||||
}
|
||||
|
||||
func (f *StringSlice) Value() []string {
|
||||
return *f
|
||||
}
|
||||
|
||||
type StringSliceFlag struct {
|
||||
Name string
|
||||
Value *StringSlice
|
||||
Usage string
|
||||
}
|
||||
|
||||
func (f StringSliceFlag) String() string {
|
||||
return fmt.Sprintf("%s%v '%v'\t%v", prefixFor(f.Name), f.Name, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
|
||||
}
|
||||
|
||||
func (f StringSliceFlag) Apply(set *flag.FlagSet) {
|
||||
set.Var(f.Value, f.Name, f.Usage)
|
||||
}
|
||||
|
||||
type IntSlice []int
|
||||
|
||||
func (f *IntSlice) Set(value string) error {
|
||||
|
||||
tmp, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
*f = append(*f, tmp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *IntSlice) String() string {
|
||||
return fmt.Sprintf("%d", *f)
|
||||
}
|
||||
|
||||
func (f *IntSlice) Value() []int {
|
||||
return *f
|
||||
}
|
||||
|
||||
type IntSliceFlag struct {
|
||||
Name string
|
||||
Value *IntSlice
|
||||
Usage string
|
||||
}
|
||||
|
||||
func (f IntSliceFlag) String() string {
|
||||
return fmt.Sprintf("%s%v '%v'\t%v", prefixFor(f.Name), f.Name, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
|
||||
}
|
||||
|
||||
func (f IntSliceFlag) Apply(set *flag.FlagSet) {
|
||||
set.Var(f.Value, f.Name, f.Usage)
|
||||
}
|
||||
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
Usage string
|
||||
|
Loading…
Reference in New Issue
Block a user