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, parsedOption, "my-option")
|
||||||
expect(t, firstArg, "my-arg")
|
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
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
Name string
|
Name string
|
||||||
ShortName string
|
ShortName string
|
||||||
Usage string
|
Usage string
|
||||||
Description string
|
Description string
|
||||||
Action func (context *Context)
|
Action func(context *Context)
|
||||||
Flags []Flag
|
Flags []Flag
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Command) Run(ctx *Context) {
|
func (c Command) Run(ctx *Context) {
|
||||||
@ -52,7 +52,6 @@ func (c Command) Run(ctx *Context) {
|
|||||||
|
|
||||||
context := NewContext(ctx.App, set, ctx.globalSet)
|
context := NewContext(ctx.App, set, ctx.globalSet)
|
||||||
checkCommandHelp(context, c.Name)
|
checkCommandHelp(context, c.Name)
|
||||||
|
|
||||||
c.Action(context)
|
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)
|
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
|
// 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 c.lookupInt(name, c.globalSet)
|
return c.lookupInt(name, c.globalSet)
|
||||||
@ -49,6 +59,16 @@ func (c *Context) GlobalString(name string) string {
|
|||||||
return c.lookupString(name, c.globalSet)
|
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 {
|
func (c *Context) Args() []string {
|
||||||
return c.flagSet.Args()
|
return c.flagSet.Args()
|
||||||
}
|
}
|
||||||
@ -75,6 +95,26 @@ func (c *Context) lookupString(name string, set *flag.FlagSet) string {
|
|||||||
return ""
|
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 {
|
func (c *Context) lookupBool(name string, set *flag.FlagSet) bool {
|
||||||
f := set.Lookup(name)
|
f := set.Lookup(name)
|
||||||
if f != nil {
|
if f != nil {
|
||||||
|
66
flag.go
66
flag.go
@ -2,6 +2,7 @@ package cli
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "flag"
|
import "flag"
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
type Flag interface {
|
type Flag interface {
|
||||||
fmt.Stringer
|
fmt.Stringer
|
||||||
@ -10,12 +11,77 @@ type Flag interface {
|
|||||||
|
|
||||||
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
||||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||||
|
|
||||||
for _, f := range flags {
|
for _, f := range flags {
|
||||||
f.Apply(set)
|
f.Apply(set)
|
||||||
}
|
}
|
||||||
return 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 {
|
type BoolFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
|
Loading…
Reference in New Issue
Block a user