From bb7e45acf18a321a6ae06bd7c8f7ead624907c67 Mon Sep 17 00:00:00 2001 From: ston1th Date: Sat, 14 Nov 2015 20:01:15 +0100 Subject: [PATCH 1/3] Added destination scan support for flags --- flag.go | 63 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/flag.go b/flag.go index 531b091..ea830f8 100644 --- a/flag.go +++ b/flag.go @@ -237,9 +237,10 @@ func (f IntSliceFlag) getName() string { // BoolFlag is a switch that defaults to false type BoolFlag struct { - Name string - Usage string - EnvVar string + Name string + Usage string + EnvVar string + Destination *bool } // String returns a readable representation of this value (for usage defaults) @@ -264,6 +265,10 @@ func (f BoolFlag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.BoolVar(f.Destination, name, val, f.Usage) + return + } set.Bool(name, val, f.Usage) }) } @@ -312,10 +317,11 @@ func (f BoolTFlag) getName() string { // StringFlag represents a flag that takes as string value type StringFlag struct { - Name string - Value string - Usage string - EnvVar string + Name string + Value string + Usage string + EnvVar string + Destination *string } // String returns the usage @@ -345,6 +351,10 @@ func (f StringFlag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.StringVar(f.Destination, name, f.Value, f.Usage) + return + } set.String(name, f.Value, f.Usage) }) } @@ -356,10 +366,11 @@ func (f StringFlag) getName() string { // IntFlag is a flag that takes an integer // Errors if the value provided cannot be parsed type IntFlag struct { - Name string - Value int - Usage string - EnvVar string + Name string + Value int + Usage string + EnvVar string + Destination *int } // String returns the usage @@ -383,6 +394,10 @@ func (f IntFlag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.IntVar(f.Destination, name, f.Value, f.Usage) + return + } set.Int(name, f.Value, f.Usage) }) } @@ -394,10 +409,11 @@ func (f IntFlag) getName() string { // DurationFlag is a flag that takes a duration specified in Go's duration // format: https://golang.org/pkg/time/#ParseDuration type DurationFlag struct { - Name string - Value time.Duration - Usage string - EnvVar string + Name string + Value time.Duration + Usage string + EnvVar string + Destination *time.Duration } // String returns a readable representation of this value (for usage defaults) @@ -421,6 +437,10 @@ func (f DurationFlag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.DurationVar(f.Destination, name, f.Value, f.Usage) + return + } set.Duration(name, f.Value, f.Usage) }) } @@ -432,10 +452,11 @@ func (f DurationFlag) getName() string { // Float64Flag is a flag that takes an float value // Errors if the value provided cannot be parsed type Float64Flag struct { - Name string - Value float64 - Usage string - EnvVar string + Name string + Value float64 + Usage string + EnvVar string + Destination *float64 } // String returns the usage @@ -458,6 +479,10 @@ func (f Float64Flag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.Float64Var(f.Destination, name, f.Value, f.Usage) + return + } set.Float64(name, f.Value, f.Usage) }) } From 25ef3682351649cc0cedf9f5bbd14399247fb33b Mon Sep 17 00:00:00 2001 From: ston1th Date: Sat, 14 Nov 2015 22:39:38 +0100 Subject: [PATCH 2/3] added destination scan testing and BoolT --- flag.go | 11 +++++-- flag_test.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/flag.go b/flag.go index ea830f8..9b22d7f 100644 --- a/flag.go +++ b/flag.go @@ -280,9 +280,10 @@ func (f BoolFlag) getName() string { // BoolTFlag this represents a boolean flag that is true by default, but can // still be set to false by --some-flag=false type BoolTFlag struct { - Name string - Usage string - EnvVar string + Name string + Usage string + EnvVar string + Destination *bool } // String returns a readable representation of this value (for usage defaults) @@ -307,6 +308,10 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) { } eachName(f.Name, func(name string) { + if f.Destination != nil { + set.BoolVar(f.Destination, name, val, f.Usage) + return + } set.Bool(name, val, f.Usage) }) } diff --git a/flag_test.go b/flag_test.go index 3606102..4462d3f 100644 --- a/flag_test.go +++ b/flag_test.go @@ -305,6 +305,24 @@ func TestParseMultiString(t *testing.T) { }).Run([]string{"run", "-s", "10"}) } +func TestParseDestinationString(t *testing.T) { + var dest string + a := App{ + Flags: []Flag{ + StringFlag{ + Name: "dest", + Destination: &dest, + }, + }, + Action: func(ctx *Context) { + if dest != "10" { + t.Errorf("expected destination String 10") + } + }, + } + a.Run([]string{"run", "--dest", "10"}) +} + func TestParseMultiStringFromEnv(t *testing.T) { os.Clearenv() os.Setenv("APP_COUNT", "20") @@ -412,6 +430,24 @@ func TestParseMultiInt(t *testing.T) { a.Run([]string{"run", "-s", "10"}) } +func TestParseDestinationInt(t *testing.T) { + var dest int + a := App{ + Flags: []Flag{ + IntFlag{ + Name: "dest", + Destination: &dest, + }, + }, + Action: func(ctx *Context) { + if dest != 10 { + t.Errorf("expected destination Int 10") + } + }, + } + a.Run([]string{"run", "--dest", "10"}) +} + func TestParseMultiIntFromEnv(t *testing.T) { os.Clearenv() os.Setenv("APP_TIMEOUT_SECONDS", "10") @@ -521,6 +557,24 @@ func TestParseMultiFloat64(t *testing.T) { a.Run([]string{"run", "-s", "10.2"}) } +func TestParseDestinationFloat64(t *testing.T) { + var dest float64 + a := App{ + Flags: []Flag{ + Float64Flag{ + Name: "dest", + Destination: &dest, + }, + }, + Action: func(ctx *Context) { + if dest != 10.2 { + t.Errorf("expected destination Float64 10.2") + } + }, + } + a.Run([]string{"run", "--dest", "10.2"}) +} + func TestParseMultiFloat64FromEnv(t *testing.T) { os.Clearenv() os.Setenv("APP_TIMEOUT_SECONDS", "15.5") @@ -576,6 +630,24 @@ func TestParseMultiBool(t *testing.T) { a.Run([]string{"run", "--serve"}) } +func TestParseDestinationBool(t *testing.T) { + var dest bool + a := App{ + Flags: []Flag{ + BoolFlag{ + Name: "dest", + Destination: &dest, + }, + }, + Action: func(ctx *Context) { + if dest != true { + t.Errorf("expected destination Bool true") + } + }, + } + a.Run([]string{"run", "--dest"}) +} + func TestParseMultiBoolFromEnv(t *testing.T) { os.Clearenv() os.Setenv("APP_DEBUG", "1") @@ -631,6 +703,24 @@ func TestParseMultiBoolT(t *testing.T) { a.Run([]string{"run", "--serve"}) } +func TestParseDestinationBoolT(t *testing.T) { + var dest bool + a := App{ + Flags: []Flag{ + BoolTFlag{ + Name: "dest", + Destination: &dest, + }, + }, + Action: func(ctx *Context) { + if dest != true { + t.Errorf("expected destination BoolT true") + } + }, + } + a.Run([]string{"run", "--dest"}) +} + func TestParseMultiBoolTFromEnv(t *testing.T) { os.Clearenv() os.Setenv("APP_DEBUG", "0") From 4579bbf129a8e607313bf03af8d24e0f79ed0aa4 Mon Sep 17 00:00:00 2001 From: ston1th Date: Sun, 15 Nov 2015 10:59:12 +0100 Subject: [PATCH 3/3] added description to README.md --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 2346557..26a1838 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,32 @@ app.Action = func(c *cli.Context) { ... ``` +You can also set a destination variable for a flag, to which the content will be scanned. +``` go +... +var language string +app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang", + Value: "english", + Usage: "language for the greeting", + Destination: &language, + }, +} +app.Action = func(c *cli.Context) { + name := "someone" + if len(c.Args()) > 0 { + name = c.Args()[0] + } + if language == "spanish" { + println("Hola", name) + } else { + println("Hello", name) + } +} +... +``` + See full list of flags at http://godoc.org/github.com/codegangsta/cli #### Alternate Names