From 6185b8d8fd27da0a3d35457ccb4dfdab261a1295 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 00:56:44 -0400 Subject: [PATCH 01/10] Generate code for flag types and context accessors --- .travis.yml | 2 + appveyor.yml | 3 + cli.go | 2 + context.go | 184 ----------------- flag-types.json | 79 ++++++++ flag.go | 261 ------------------------- flag_generated.go | 467 ++++++++++++++++++++++++++++++++++++++++++++ generate-flag-types | 116 +++++++++++ runtests | 18 +- 9 files changed, 682 insertions(+), 450 deletions(-) create mode 100644 flag-types.json create mode 100644 flag_generated.go create mode 100755 generate-flag-types diff --git a/.travis.yml b/.travis.yml index 273d017..905a9cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,11 +29,13 @@ matrix: before_script: - go get github.com/urfave/gfmxr/... +- go get golang.org/x/tools/cmd/goimports - if [ ! -f node_modules/.bin/markdown-toc ] ; then npm install markdown-toc ; fi script: +- ./runtests gen - ./runtests vet - ./runtests test - ./runtests gfmxr diff --git a/appveyor.yml b/appveyor.yml index 173086e..ae91ae8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,9 +17,12 @@ install: - go version - go env - go get github.com/urfave/gfmxr/... +- go get golang.org/x/tools/cmd/goimports - go get -v -t ./... build_script: +- python runtests gen - python runtests vet - python runtests test - python runtests gfmxr +- python runtests toc diff --git a/cli.go b/cli.go index f0440c5..1e53dbf 100644 --- a/cli.go +++ b/cli.go @@ -17,3 +17,5 @@ // app.Run(os.Args) // } package cli + +//go:generate python ./generate-flag-types flag_generated.go flag-types.json diff --git a/context.go b/context.go index 879bae5..762d389 100644 --- a/context.go +++ b/context.go @@ -26,190 +26,6 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { return &Context{App: app, flagSet: set, parentContext: parentCtx} } -// Int looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Int(name string) int { - return lookupInt(name, c.flagSet) -} - -// Int64 looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Int64(name string) int64 { - return lookupInt64(name, c.flagSet) -} - -// Uint looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Uint(name string) uint { - return lookupUint(name, c.flagSet) -} - -// Uint64 looks up the value of a local int flag, returns 0 if no int flag exists -func (c *Context) Uint64(name string) uint64 { - return lookupUint64(name, c.flagSet) -} - -// Duration looks up the value of a local time.Duration flag, returns 0 if no -// time.Duration flag exists -func (c *Context) Duration(name string) time.Duration { - return lookupDuration(name, c.flagSet) -} - -// Float64 looks up the value of a local float64 flag, returns 0 if no float64 -// flag exists -func (c *Context) Float64(name string) float64 { - return lookupFloat64(name, c.flagSet) -} - -// Bool looks up the value of a local bool flag, returns false if no bool flag exists -func (c *Context) Bool(name string) bool { - return lookupBool(name, c.flagSet) -} - -// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists -func (c *Context) BoolT(name string) bool { - return lookupBoolT(name, c.flagSet) -} - -// String looks up the value of a local string flag, returns "" if no string flag exists -func (c *Context) String(name string) string { - return lookupString(name, c.flagSet) -} - -// StringSlice 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 lookupStringSlice(name, c.flagSet) -} - -// IntSlice 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 lookupIntSlice(name, c.flagSet) -} - -// Int64Slice looks up the value of a local int slice flag, returns nil if no int -// slice flag exists -func (c *Context) Int64Slice(name string) []int64 { - return lookupInt64Slice(name, c.flagSet) -} - -// Generic 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) -} - -// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalInt(name string) int { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt(name, fs) - } - return 0 -} - -// GlobalInt64 looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalInt64(name string) int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt64(name, fs) - } - return 0 -} - -// GlobalUint looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalUint(name string) uint { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupUint(name, fs) - } - return 0 -} - -// GlobalUint64 looks up the value of a global int flag, returns 0 if no int flag exists -func (c *Context) GlobalUint64(name string) uint64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupUint64(name, fs) - } - return 0 -} - -// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0) -// if no float64 flag exists -func (c *Context) GlobalFloat64(name string) float64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupFloat64(name, fs) - } - return float64(0) -} - -// GlobalDuration looks up the value of a global time.Duration flag, returns 0 -// if no time.Duration flag exists -func (c *Context) GlobalDuration(name string) time.Duration { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupDuration(name, fs) - } - return 0 -} - -// GlobalBool looks up the value of a global bool flag, returns false if no bool -// flag exists -func (c *Context) GlobalBool(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupBool(name, fs) - } - return false -} - -// GlobalBoolT looks up the value of a global bool flag, returns true if no bool -// flag exists -func (c *Context) GlobalBoolT(name string) bool { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupBoolT(name, fs) - } - return false -} - -// GlobalString looks up the value of a global string flag, returns "" if no -// string flag exists -func (c *Context) GlobalString(name string) string { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupString(name, fs) - } - return "" -} - -// GlobalStringSlice 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 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupStringSlice(name, fs) - } - return nil -} - -// GlobalIntSlice 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 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupIntSlice(name, fs) - } - return nil -} - -// GlobalInt64Slice looks up the value of a global int slice flag, returns nil if -// no int slice flag exists -func (c *Context) GlobalInt64Slice(name string) []int64 { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupInt64Slice(name, fs) - } - return nil -} - -// GlobalGeneric looks up the value of a global generic flag, returns nil if no -// generic flag exists -func (c *Context) GlobalGeneric(name string) interface{} { - if fs := lookupGlobalFlagSet(name, c); fs != nil { - return lookupGeneric(name, fs) - } - return nil -} - // NumFlags returns the number of flags set func (c *Context) NumFlags() int { return c.flagSet.NFlag() diff --git a/flag-types.json b/flag-types.json new file mode 100644 index 0000000..2085350 --- /dev/null +++ b/flag-types.json @@ -0,0 +1,79 @@ +[ + { + "name": "Bool", + "type": "bool", + "value": false, + "context_default": "false" + }, + { + "name": "BoolT", + "type": "bool", + "value": false, + "doctail": " that is true by default", + "context_default": "false" + }, + { + "name": "Duration", + "type": "time.Duration", + "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", + "context_default": "0" + }, + { + "name": "Float64", + "type": "float64", + "context_default": "0" + }, + { + "name": "Generic", + "type": "Generic", + "dest": false, + "context_default": "nil", + "context_type": "interface{}" + }, + { + "name": "Int64", + "type": "int64", + "context_default": "0" + }, + { + "name": "Int", + "type": "int", + "context_default": "0" + }, + { + "name": "IntSlice", + "type": "*IntSlice", + "dest": false, + "context_default": "nil", + "context_type": "[]int" + }, + { + "name": "Int64Slice", + "type": "*Int64Slice", + "dest": false, + "context_default": "nil", + "context_type": "[]int64" + }, + { + "name": "String", + "type": "string", + "context_default": "\"\"" + }, + { + "name": "StringSlice", + "type": "*StringSlice", + "dest": false, + "context_default": "nil", + "context_type": "[]string" + }, + { + "name": "Uint64", + "type": "uint64", + "context_default": "0" + }, + { + "name": "Uint", + "type": "uint", + "context_default": "0" + } +] diff --git a/flag.go b/flag.go index f8a28d1..e748c02 100644 --- a/flag.go +++ b/flag.go @@ -70,22 +70,6 @@ type Generic interface { String() string } -// GenericFlag is the flag type for types implementing Generic -type GenericFlag struct { - Name string - Value Generic - Usage string - EnvVar string - Hidden bool -} - -// String returns the string representation of the generic flag to display the -// help text to the user (uses the String() method of the generic flag to show -// the value) -func (f GenericFlag) String() string { - return FlagStringer(f) -} - // Apply takes the flagset and calls Set on the generic flag with the value // provided by the user for parsing by the flag func (f GenericFlag) Apply(set *flag.FlagSet) { @@ -105,11 +89,6 @@ func (f GenericFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of a flag. -func (f GenericFlag) GetName() string { - return f.Name -} - // StringSlice is an opaque type for []string to satisfy flag.Value type StringSlice []string @@ -129,21 +108,6 @@ func (f *StringSlice) Value() []string { return *f } -// StringSliceFlag is a string flag that can be specified multiple times on the -// command-line -type StringSliceFlag struct { - Name string - Value *StringSlice - Usage string - EnvVar string - Hidden bool -} - -// String returns the usage -func (f StringSliceFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f StringSliceFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -169,11 +133,6 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of a flag. -func (f StringSliceFlag) GetName() string { - return f.Name -} - // IntSlice is an opaque type for []int to satisfy flag.Value type IntSlice []int @@ -197,21 +156,6 @@ func (f *IntSlice) Value() []int { return *f } -// IntSliceFlag is an int flag that can be specified multiple times on the -// command-line -type IntSliceFlag struct { - Name string - Value *IntSlice - Usage string - EnvVar string - Hidden bool -} - -// String returns the usage -func (f IntSliceFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f IntSliceFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -240,11 +184,6 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f IntSliceFlag) GetName() string { - return f.Name -} - // Int64Slice is an opaque type for []int to satisfy flag.Value type Int64Slice []int64 @@ -268,21 +207,6 @@ func (f *Int64Slice) Value() []int64 { return *f } -// Int64SliceFlag is an int flag that can be specified multiple times on the -// command-line -type Int64SliceFlag struct { - Name string - Value *Int64Slice - Usage string - EnvVar string - Hidden bool -} - -// String returns the usage -func (f Int64SliceFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f Int64SliceFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -311,25 +235,6 @@ func (f Int64SliceFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f Int64SliceFlag) GetName() string { - return f.Name -} - -// BoolFlag is a switch that defaults to false -type BoolFlag struct { - Name string - Usage string - EnvVar string - Destination *bool - Hidden bool -} - -// String returns a readable representation of this value (for usage defaults) -func (f BoolFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f BoolFlag) Apply(set *flag.FlagSet) { val := false @@ -355,26 +260,6 @@ func (f BoolFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f BoolFlag) GetName() string { - return f.Name -} - -// 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 - Destination *bool - Hidden bool -} - -// String returns a readable representation of this value (for usage defaults) -func (f BoolTFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f BoolTFlag) Apply(set *flag.FlagSet) { val := true @@ -400,26 +285,6 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f BoolTFlag) GetName() string { - return f.Name -} - -// StringFlag represents a flag that takes as string value -type StringFlag struct { - Name string - Value string - Usage string - EnvVar string - Destination *string - Hidden bool -} - -// String returns the usage -func (f StringFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f StringFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -441,26 +306,6 @@ func (f StringFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f StringFlag) GetName() string { - return f.Name -} - -// IntFlag is a flag that takes an integer -type IntFlag struct { - Name string - Value int - Usage string - EnvVar string - Destination *int - Hidden bool -} - -// String returns the usage -func (f IntFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f IntFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -485,26 +330,6 @@ func (f IntFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f IntFlag) GetName() string { - return f.Name -} - -// Int64Flag is a flag that takes a 64-bit integer -type Int64Flag struct { - Name string - Value int64 - Usage string - EnvVar string - Destination *int64 - Hidden bool -} - -// String returns the usage -func (f Int64Flag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f Int64Flag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -529,26 +354,6 @@ func (f Int64Flag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f Int64Flag) GetName() string { - return f.Name -} - -// UintFlag is a flag that takes an unsigned integer -type UintFlag struct { - Name string - Value uint - Usage string - EnvVar string - Destination *uint - Hidden bool -} - -// String returns the usage -func (f UintFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f UintFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -573,26 +378,6 @@ func (f UintFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f UintFlag) GetName() string { - return f.Name -} - -// Uint64Flag is a flag that takes an unsigned 64-bit integer -type Uint64Flag struct { - Name string - Value uint64 - Usage string - EnvVar string - Destination *uint64 - Hidden bool -} - -// String returns the usage -func (f Uint64Flag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f Uint64Flag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -617,27 +402,6 @@ func (f Uint64Flag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f Uint64Flag) GetName() string { - return f.Name -} - -// 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 - Destination *time.Duration - Hidden bool -} - -// String returns a readable representation of this value (for usage defaults) -func (f DurationFlag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f DurationFlag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -662,26 +426,6 @@ func (f DurationFlag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f DurationFlag) GetName() string { - return f.Name -} - -// Float64Flag is a flag that takes an float value -type Float64Flag struct { - Name string - Value float64 - Usage string - EnvVar string - Destination *float64 - Hidden bool -} - -// String returns the usage -func (f Float64Flag) String() string { - return FlagStringer(f) -} - // Apply populates the flag given the flag set and environment func (f Float64Flag) Apply(set *flag.FlagSet) { if f.EnvVar != "" { @@ -705,11 +449,6 @@ func (f Float64Flag) Apply(set *flag.FlagSet) { }) } -// GetName returns the name of the flag. -func (f Float64Flag) GetName() string { - return f.Name -} - func visibleFlags(fl []Flag) []Flag { visible := []Flag{} for _, flag := range fl { diff --git a/flag_generated.go b/flag_generated.go new file mode 100644 index 0000000..5cbdb83 --- /dev/null +++ b/flag_generated.go @@ -0,0 +1,467 @@ +package cli + +import "time" + +// WARNING: This file is generated! + +// BoolFlag is a flag with type bool +type BoolFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Destination *bool +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f BoolFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f BoolFlag) GetName() string { + return f.Name +} + +// Bool looks up the value of a local BoolFlag, returns +// false if not found +func (c *Context) Bool(name string) bool { + return lookupBool(name, c.flagSet) +} + +// GlobalBool looks up the value of a global BoolFlag, returns +// false if not found +func (c *Context) GlobalBool(name string) bool { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupBool(name, fs) + } + return false +} + +// BoolTFlag is a flag with type bool that is true by default +type BoolTFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Destination *bool +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f BoolTFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f BoolTFlag) GetName() string { + return f.Name +} + +// BoolT looks up the value of a local BoolTFlag, returns +// false if not found +func (c *Context) BoolT(name string) bool { + return lookupBoolT(name, c.flagSet) +} + +// GlobalBoolT looks up the value of a global BoolTFlag, returns +// false if not found +func (c *Context) GlobalBoolT(name string) bool { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupBoolT(name, fs) + } + return false +} + +// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) +type DurationFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value time.Duration + Destination *time.Duration +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f DurationFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f DurationFlag) GetName() string { + return f.Name +} + +// Duration looks up the value of a local DurationFlag, returns +// 0 if not found +func (c *Context) Duration(name string) time.Duration { + return lookupDuration(name, c.flagSet) +} + +// GlobalDuration looks up the value of a global DurationFlag, returns +// 0 if not found +func (c *Context) GlobalDuration(name string) time.Duration { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupDuration(name, fs) + } + return 0 +} + +// Float64Flag is a flag with type float64 +type Float64Flag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value float64 + Destination *float64 +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f Float64Flag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f Float64Flag) GetName() string { + return f.Name +} + +// Float64 looks up the value of a local Float64Flag, returns +// 0 if not found +func (c *Context) Float64(name string) float64 { + return lookupFloat64(name, c.flagSet) +} + +// GlobalFloat64 looks up the value of a global Float64Flag, returns +// 0 if not found +func (c *Context) GlobalFloat64(name string) float64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupFloat64(name, fs) + } + return 0 +} + +// GenericFlag is a flag with type Generic +type GenericFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value Generic +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f GenericFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f GenericFlag) GetName() string { + return f.Name +} + +// Generic looks up the value of a local GenericFlag, returns +// nil if not found +func (c *Context) Generic(name string) interface{} { + return lookupGeneric(name, c.flagSet) +} + +// GlobalGeneric looks up the value of a global GenericFlag, returns +// nil if not found +func (c *Context) GlobalGeneric(name string) interface{} { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupGeneric(name, fs) + } + return nil +} + +// Int64Flag is a flag with type int64 +type Int64Flag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value int64 + Destination *int64 +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f Int64Flag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f Int64Flag) GetName() string { + return f.Name +} + +// Int64 looks up the value of a local Int64Flag, returns +// 0 if not found +func (c *Context) Int64(name string) int64 { + return lookupInt64(name, c.flagSet) +} + +// GlobalInt64 looks up the value of a global Int64Flag, returns +// 0 if not found +func (c *Context) GlobalInt64(name string) int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64(name, fs) + } + return 0 +} + +// IntFlag is a flag with type int +type IntFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value int + Destination *int +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f IntFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f IntFlag) GetName() string { + return f.Name +} + +// Int looks up the value of a local IntFlag, returns +// 0 if not found +func (c *Context) Int(name string) int { + return lookupInt(name, c.flagSet) +} + +// GlobalInt looks up the value of a global IntFlag, returns +// 0 if not found +func (c *Context) GlobalInt(name string) int { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt(name, fs) + } + return 0 +} + +// IntSliceFlag is a flag with type *IntSlice +type IntSliceFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value *IntSlice +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f IntSliceFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f IntSliceFlag) GetName() string { + return f.Name +} + +// IntSlice looks up the value of a local IntSliceFlag, returns +// nil if not found +func (c *Context) IntSlice(name string) []int { + return lookupIntSlice(name, c.flagSet) +} + +// GlobalIntSlice looks up the value of a global IntSliceFlag, returns +// nil if not found +func (c *Context) GlobalIntSlice(name string) []int { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupIntSlice(name, fs) + } + return nil +} + +// Int64SliceFlag is a flag with type *Int64Slice +type Int64SliceFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value *Int64Slice +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f Int64SliceFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f Int64SliceFlag) GetName() string { + return f.Name +} + +// Int64Slice looks up the value of a local Int64SliceFlag, returns +// nil if not found +func (c *Context) Int64Slice(name string) []int64 { + return lookupInt64Slice(name, c.flagSet) +} + +// GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns +// nil if not found +func (c *Context) GlobalInt64Slice(name string) []int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64Slice(name, fs) + } + return nil +} + +// StringFlag is a flag with type string +type StringFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value string + Destination *string +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f StringFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f StringFlag) GetName() string { + return f.Name +} + +// String looks up the value of a local StringFlag, returns +// "" if not found +func (c *Context) String(name string) string { + return lookupString(name, c.flagSet) +} + +// GlobalString looks up the value of a global StringFlag, returns +// "" if not found +func (c *Context) GlobalString(name string) string { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupString(name, fs) + } + return "" +} + +// StringSliceFlag is a flag with type *StringSlice +type StringSliceFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value *StringSlice +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f StringSliceFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f StringSliceFlag) GetName() string { + return f.Name +} + +// StringSlice looks up the value of a local StringSliceFlag, returns +// nil if not found +func (c *Context) StringSlice(name string) []string { + return lookupStringSlice(name, c.flagSet) +} + +// GlobalStringSlice looks up the value of a global StringSliceFlag, returns +// nil if not found +func (c *Context) GlobalStringSlice(name string) []string { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupStringSlice(name, fs) + } + return nil +} + +// Uint64Flag is a flag with type uint64 +type Uint64Flag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value uint64 + Destination *uint64 +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f Uint64Flag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f Uint64Flag) GetName() string { + return f.Name +} + +// Uint64 looks up the value of a local Uint64Flag, returns +// 0 if not found +func (c *Context) Uint64(name string) uint64 { + return lookupUint64(name, c.flagSet) +} + +// GlobalUint64 looks up the value of a global Uint64Flag, returns +// 0 if not found +func (c *Context) GlobalUint64(name string) uint64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint64(name, fs) + } + return 0 +} + +// UintFlag is a flag with type uint +type UintFlag struct { + Name string + Usage string + EnvVar string + Hidden bool + Value uint + Destination *uint +} + +// String returns a readable representation of this value +// (for usage defaults) +func (f UintFlag) String() string { + return FlagStringer(f) +} + +// GetName returns the name of the flag +func (f UintFlag) GetName() string { + return f.Name +} + +// Uint looks up the value of a local UintFlag, returns +// 0 if not found +func (c *Context) Uint(name string) uint { + return lookupUint(name, c.flagSet) +} + +// GlobalUint looks up the value of a global UintFlag, returns +// 0 if not found +func (c *Context) GlobalUint(name string) uint { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint(name, fs) + } + return 0 +} diff --git a/generate-flag-types b/generate-flag-types new file mode 100755 index 0000000..7fea977 --- /dev/null +++ b/generate-flag-types @@ -0,0 +1,116 @@ +#!/usr/bin/env python + +from __future__ import print_function, unicode_literals + +import io +import json +import os +import subprocess +import sys +import textwrap + + +def main(sysargs=sys.argv[:]): + _generate_flag_types(sys.argv[1], sys.argv[2]) + return 0 + + +def _generate_flag_types(output_filename, types_filename): + try: + types = _load_types(types_filename) + if os.path.exists(output_filename): + os.chmod(output_filename, 0644) + + with io.open(output_filename, 'w', encoding='utf-8') as outfile: + _write_flag_types(outfile, types) + + new_content = subprocess.check_output( + ['goimports', output_filename] + ).decode('utf-8') + + with io.open(output_filename, 'w', encoding='utf-8') as outfile: + print(new_content, file=outfile, end='') + + finally: + if os.path.exists(output_filename): + os.chmod(output_filename, 0444) + + +def _load_types(types_filename): + with io.open(types_filename, encoding='utf-8') as infile: + return json.load(infile) + + +def _write_flag_types(outfile, types): + _fwrite(outfile, """\ + package cli + + // WARNING: This file is generated! + + """) + + for typedef in types: + typedef.setdefault('doctail', '') + typedef.setdefault('context_type', typedef['type']) + typedef.setdefault('struct', True) + typedef.setdefault('dest', True) + typedef.setdefault('value', True) + + if typedef['struct']: + _fwrite(outfile, """\ + // {name}Flag is a flag with type {type}{doctail} + type {name}Flag struct {{ + Name string + Usage string + EnvVar string + Hidden bool + """.format(**typedef)) + + if typedef['value']: + _fwrite(outfile, """\ + Value {type} + """.format(**typedef)) + + if typedef['dest']: + _fwrite(outfile, """\ + Destination *{type} + """.format(**typedef)) + + _fwrite(outfile, "\n}\n\n") + + _fwrite(outfile, """\ + // String returns a readable representation of this value + // (for usage defaults) + func (f {name}Flag) String() string {{ + return FlagStringer(f) + }} + + // GetName returns the name of the flag + func (f {name}Flag) GetName() string {{ + return f.Name + }} + + // {name} looks up the value of a local {name}Flag, returns + // {context_default} if not found + func (c *Context) {name}(name string) {context_type} {{ + return lookup{name}(name, c.flagSet) + }} + + // Global{name} looks up the value of a global {name}Flag, returns + // {context_default} if not found + func (c *Context) Global{name}(name string) {context_type} {{ + if fs := lookupGlobalFlagSet(name, c); fs != nil {{ + return lookup{name}(name, fs) + }} + return {context_default} + }} + + """.format(**typedef)) + + +def _fwrite(outfile, text): + print(textwrap.dedent(text), end='', file=outfile) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/runtests b/runtests index 0a7b483..4fa4e1e 100755 --- a/runtests +++ b/runtests @@ -20,6 +20,7 @@ def main(sysargs=sys.argv[:]): 'test': _test, 'gfmxr': _gfmxr, 'toc': _toc, + 'gen': _gen, } parser = argparse.ArgumentParser() @@ -34,7 +35,7 @@ def main(sysargs=sys.argv[:]): def _test(): if check_output('go version'.split()).split()[2] < 'go1.2': - _run('go test -v .'.split()) + _run('go test -v .') return coverprofiles = [] @@ -51,7 +52,7 @@ def _test(): ]) combined_name = _combine_coverprofiles(coverprofiles) - _run('go tool cover -func={}'.format(combined_name).split()) + _run('go tool cover -func={}'.format(combined_name)) os.remove(combined_name) @@ -60,15 +61,22 @@ def _gfmxr(): def _vet(): - _run('go vet ./...'.split()) + _run('go vet ./...') def _toc(): - _run(['node_modules/.bin/markdown-toc', '-i', 'README.md']) - _run(['git', 'diff', '--quiet']) + _run('node_modules/.bin/markdown-toc -i README.md') + _run('git diff --quiet') + + +def _gen(): + _run('go generate .') + _run('git diff --quiet') def _run(command): + if hasattr(command, 'split'): + command = command.split() print('runtests: {}'.format(' '.join(command)), file=sys.stderr) check_call(command) From d1081fb23f2091cbb571cd8f1ae882f2507ee468 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 01:08:19 -0400 Subject: [PATCH 02/10] Skip go generate check on older versions --- runtests | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtests b/runtests index 4fa4e1e..7066932 100755 --- a/runtests +++ b/runtests @@ -70,6 +70,11 @@ def _toc(): def _gen(): + go_version = check_output('go version'.split()).split()[2] + if go_version < 'go1.4': + print('runtests: skip on {}'.format(go_version), file=sys.stderr) + return + _run('go generate .') _run('git diff --quiet') From 2455dd1f29d401e80df49f8914f6eccb759b7a79 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 01:09:21 -0400 Subject: [PATCH 03/10] Skip go generate test on Windows --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ae91ae8..f37ab9e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,11 +17,9 @@ install: - go version - go env - go get github.com/urfave/gfmxr/... -- go get golang.org/x/tools/cmd/goimports - go get -v -t ./... build_script: -- python runtests gen - python runtests vet - python runtests test - python runtests gfmxr From 1a9f445800d5282fe41f3939d868b05bb436a4b4 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 09:42:02 -0400 Subject: [PATCH 04/10] Try to run markdown-toc on Windows again (???) --- runtests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtests b/runtests index 7066932..77a4c44 100755 --- a/runtests +++ b/runtests @@ -65,7 +65,7 @@ def _vet(): def _toc(): - _run('node_modules/.bin/markdown-toc -i README.md') + _run('bash node_modules/.bin/markdown-toc -i README.md') _run('git diff --quiet') From ee0375e901f6c9dd041ea59f152add693f0d0314 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 09:42:33 -0400 Subject: [PATCH 05/10] Nope, forget about toc on Windows --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index f37ab9e..173086e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,4 +23,3 @@ build_script: - python runtests vet - python runtests test - python runtests gfmxr -- python runtests toc From 111ea8b9d305f5baf383934c0aaead5f79dfd5eb Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Thu, 23 Jun 2016 09:59:04 -0400 Subject: [PATCH 06/10] Unbreak runtests toc target --- runtests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtests b/runtests index 77a4c44..7066932 100755 --- a/runtests +++ b/runtests @@ -65,7 +65,7 @@ def _vet(): def _toc(): - _run('bash node_modules/.bin/markdown-toc -i README.md') + _run('node_modules/.bin/markdown-toc -i README.md') _run('git diff --quiet') From 3a8ad862a66b30452bd9e10ee5c7a60d4a86fcb7 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sun, 10 Jul 2016 12:26:09 -0400 Subject: [PATCH 07/10] Add help text/docs for generate-flag-types script --- cli.go | 2 +- generate-flag-types | 142 +++++++++++++++++++++++++++++++------------- runtests | 4 +- 3 files changed, 104 insertions(+), 44 deletions(-) diff --git a/cli.go b/cli.go index 1e53dbf..1247a84 100644 --- a/cli.go +++ b/cli.go @@ -18,4 +18,4 @@ // } package cli -//go:generate python ./generate-flag-types flag_generated.go flag-types.json +//go:generate python ./generate-flag-types -i flag-types.json -o flag_generated.go diff --git a/generate-flag-types b/generate-flag-types index 7fea977..fc25349 100755 --- a/generate-flag-types +++ b/generate-flag-types @@ -1,44 +1,106 @@ #!/usr/bin/env python +""" +The flag types that ship with the cli library have many things in common, and +so we can take advantage of the `go generate` command to create much of the +source code from a list of definitions. These definitions attempt to cover +the parts that vary between flag types, and should evolve as needed. + +An example of the minimum definition needed is: + + { + "name": "SomeType", + "type": "sometype", + "context_default": "nil" + } + +In this example, the generated code will include a type named `SomeTypeFlag` +that is expected to wrap a value of type `sometype`. Fetching values by name +via `*cli.Context` will default to a value of `nil`. + +A more complete, albeit somewhat redundant, example showing all available +definition keys is: + + { + "name": "VeryMuchType", + "type": "*VeryMuchType", + "value": true, + "dest": false, + "doctail": " which really only wraps a []float64, oh well!", + "context_type": "[]float64", + "context_default": "nil" + } + +The meaning of each field is as follows: + + name (string) - The type "name", which will be suffixed with + `Flag` when generating the type definition + type (string) - The type that the generated `Flag` type is + expected to "contain" as its `.Value` member + value (bool) - Should the generated type have a `Value` member? + dest (bool) - Should the generated type support a destination + pointer? + doctail (string) - Additional docs for the flag type comment + context_type (string) - The literal type used in the `*cli.Context` + reader func signature + context_default (string) - The literal value used as the default by the + `*cli.Context` reader funcs when no value is + present + +""" from __future__ import print_function, unicode_literals -import io +import argparse import json import os import subprocess import sys +import tempfile import textwrap -def main(sysargs=sys.argv[:]): - _generate_flag_types(sys.argv[1], sys.argv[2]) - return 0 - +class _FancyFormatter(argparse.ArgumentDefaultsHelpFormatter, + argparse.RawDescriptionHelpFormatter): + pass -def _generate_flag_types(output_filename, types_filename): - try: - types = _load_types(types_filename) - if os.path.exists(output_filename): - os.chmod(output_filename, 0644) - with io.open(output_filename, 'w', encoding='utf-8') as outfile: - _write_flag_types(outfile, types) +def main(sysargs=sys.argv[:]): + parser = argparse.ArgumentParser( + description='Generate flag type code!', + formatter_class=_FancyFormatter) + parser.add_argument( + '-i', '--in-json', + type=argparse.FileType('r'), + default=sys.stdin, + help='Input JSON file which defines each type to be generated' + ) + parser.add_argument( + '-o', '--out-go', + type=argparse.FileType('w'), + default=sys.stdout, + help='Output file/stream to which generated source will be written' + ) + parser.epilog = __doc__ + + args = parser.parse_args(sysargs[1:]) + _generate_flag_types(args.out_go, args.in_json) + return 0 - new_content = subprocess.check_output( - ['goimports', output_filename] - ).decode('utf-8') - with io.open(output_filename, 'w', encoding='utf-8') as outfile: - print(new_content, file=outfile, end='') +def _generate_flag_types(output_go, input_json): + types = json.load(input_json) - finally: - if os.path.exists(output_filename): - os.chmod(output_filename, 0444) + tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False) + _write_flag_types(tmp, types) + tmp.close() + new_content = subprocess.check_output( + ['goimports', tmp.name] + ).decode('utf-8') -def _load_types(types_filename): - with io.open(types_filename, encoding='utf-8') as infile: - return json.load(infile) + print(new_content, file=output_go, end='') + output_go.flush() + os.remove(tmp.name) def _write_flag_types(outfile, types): @@ -52,31 +114,29 @@ def _write_flag_types(outfile, types): for typedef in types: typedef.setdefault('doctail', '') typedef.setdefault('context_type', typedef['type']) - typedef.setdefault('struct', True) typedef.setdefault('dest', True) typedef.setdefault('value', True) - if typedef['struct']: + _fwrite(outfile, """\ + // {name}Flag is a flag with type {type}{doctail} + type {name}Flag struct {{ + Name string + Usage string + EnvVar string + Hidden bool + """.format(**typedef)) + + if typedef['value']: _fwrite(outfile, """\ - // {name}Flag is a flag with type {type}{doctail} - type {name}Flag struct {{ - Name string - Usage string - EnvVar string - Hidden bool + Value {type} """.format(**typedef)) - if typedef['value']: - _fwrite(outfile, """\ - Value {type} - """.format(**typedef)) - - if typedef['dest']: - _fwrite(outfile, """\ - Destination *{type} - """.format(**typedef)) + if typedef['dest']: + _fwrite(outfile, """\ + Destination *{type} + """.format(**typedef)) - _fwrite(outfile, "\n}\n\n") + _fwrite(outfile, "\n}\n\n") _fwrite(outfile, """\ // String returns a readable representation of this value diff --git a/runtests b/runtests index 7066932..fda1564 100755 --- a/runtests +++ b/runtests @@ -66,7 +66,7 @@ def _vet(): def _toc(): _run('node_modules/.bin/markdown-toc -i README.md') - _run('git diff --quiet') + _run('git diff --exit-code') def _gen(): @@ -76,7 +76,7 @@ def _gen(): return _run('go generate .') - _run('git diff --quiet') + _run('git diff --exit-code') def _run(command): From 77f1130e6514c23e8de3777a57755b2af063bafc Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sun, 10 Jul 2016 12:50:57 -0400 Subject: [PATCH 08/10] Generate flag type lookup funcs --- context.go | 152 ----------------------------------------- flag-types.json | 38 +++++++---- flag_generated.go | 162 +++++++++++++++++++++++++++++++++++++++++++- generate-flag-types | 24 ++++++- 4 files changed, 209 insertions(+), 167 deletions(-) diff --git a/context.go b/context.go index 762d389..14ad3f7 100644 --- a/context.go +++ b/context.go @@ -3,9 +3,7 @@ package cli import ( "errors" "flag" - "strconv" "strings" - "time" ) // Context is a type that is passed through to @@ -173,156 +171,6 @@ func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { return nil } -func lookupInt(name string, set *flag.FlagSet) int { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseInt(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return int(val) - } - - return 0 -} - -func lookupInt64(name string, set *flag.FlagSet) int64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseInt(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupUint(name string, set *flag.FlagSet) uint { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseUint(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return uint(val) - } - - return 0 -} - -func lookupUint64(name string, set *flag.FlagSet) uint64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseUint(f.Value.String(), 0, 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupDuration(name string, set *flag.FlagSet) time.Duration { - f := set.Lookup(name) - if f != nil { - val, err := time.ParseDuration(f.Value.String()) - if err == nil { - return val - } - } - - return 0 -} - -func lookupFloat64(name string, set *flag.FlagSet) float64 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseFloat(f.Value.String(), 64) - if err != nil { - return 0 - } - return val - } - - return 0 -} - -func lookupString(name string, set *flag.FlagSet) string { - f := set.Lookup(name) - if f != nil { - return f.Value.String() - } - - return "" -} - -func lookupStringSlice(name string, set *flag.FlagSet) []string { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*StringSlice)).Value() - - } - - return nil -} - -func lookupIntSlice(name string, set *flag.FlagSet) []int { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*IntSlice)).Value() - - } - - return nil -} - -func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { - f := set.Lookup(name) - if f != nil { - return (f.Value.(*Int64Slice)).Value() - - } - - 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 { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return false - } - return val - } - - return false -} - -func lookupBoolT(name string, set *flag.FlagSet) bool { - f := set.Lookup(name) - if f != nil { - val, err := strconv.ParseBool(f.Value.String()) - if err != nil { - return true - } - return val - } - - return false -} - func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { switch ff.Value.(type) { case *StringSlice: diff --git a/flag-types.json b/flag-types.json index 2085350..1223107 100644 --- a/flag-types.json +++ b/flag-types.json @@ -3,25 +3,29 @@ "name": "Bool", "type": "bool", "value": false, - "context_default": "false" + "context_default": "false", + "parser": "strconv.ParseBool(f.Value.String())" }, { "name": "BoolT", "type": "bool", "value": false, "doctail": " that is true by default", - "context_default": "false" + "context_default": "false", + "parser": "strconv.ParseBool(f.Value.String())" }, { "name": "Duration", "type": "time.Duration", "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", - "context_default": "0" + "context_default": "0", + "parser": "time.ParseDuration(f.Value.String())" }, { "name": "Float64", "type": "float64", - "context_default": "0" + "context_default": "0", + "parser": "strconv.ParseFloat(f.Value.String(), 64)" }, { "name": "Generic", @@ -33,47 +37,57 @@ { "name": "Int64", "type": "int64", - "context_default": "0" + "context_default": "0", + "parser": "strconv.ParseInt(f.Value.String(), 0, 64)" }, { "name": "Int", "type": "int", - "context_default": "0" + "context_default": "0", + "parser": "strconv.ParseInt(f.Value.String(), 0, 64)", + "parser_cast": "int(parsed)" }, { "name": "IntSlice", "type": "*IntSlice", "dest": false, "context_default": "nil", - "context_type": "[]int" + "context_type": "[]int", + "parser": "(f.Value.(*IntSlice)).Value(), error(nil)" }, { "name": "Int64Slice", "type": "*Int64Slice", "dest": false, "context_default": "nil", - "context_type": "[]int64" + "context_type": "[]int64", + "parser": "(f.Value.(*Int64Slice)).Value(), error(nil)" }, { "name": "String", "type": "string", - "context_default": "\"\"" + "context_default": "\"\"", + "parser": "f.Value.String(), error(nil)" }, { "name": "StringSlice", "type": "*StringSlice", "dest": false, "context_default": "nil", - "context_type": "[]string" + "context_type": "[]string", + "parser": "(f.Value.(*StringSlice)).Value(), error(nil)" }, { "name": "Uint64", "type": "uint64", - "context_default": "0" + "context_default": "0", + "parser": "strconv.ParseUint(f.Value.String(), 0, 64)" }, { "name": "Uint", "type": "uint", - "context_default": "0" + "context_default": "0", + "parser": "strconv.ParseUint(f.Value.String(), 0, 64)", + "parser_cast": "uint(parsed)" } ] diff --git a/flag_generated.go b/flag_generated.go index 5cbdb83..491b619 100644 --- a/flag_generated.go +++ b/flag_generated.go @@ -1,6 +1,10 @@ package cli -import "time" +import ( + "flag" + "strconv" + "time" +) // WARNING: This file is generated! @@ -39,6 +43,18 @@ func (c *Context) GlobalBool(name string) bool { return false } +func lookupBool(name string, set *flag.FlagSet) bool { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseBool(f.Value.String()) + if err != nil { + return false + } + return parsed + } + return false +} + // BoolTFlag is a flag with type bool that is true by default type BoolTFlag struct { Name string @@ -74,6 +90,18 @@ func (c *Context) GlobalBoolT(name string) bool { return false } +func lookupBoolT(name string, set *flag.FlagSet) bool { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseBool(f.Value.String()) + if err != nil { + return false + } + return parsed + } + return false +} + // DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) type DurationFlag struct { Name string @@ -110,6 +138,18 @@ func (c *Context) GlobalDuration(name string) time.Duration { return 0 } +func lookupDuration(name string, set *flag.FlagSet) time.Duration { + f := set.Lookup(name) + if f != nil { + parsed, err := time.ParseDuration(f.Value.String()) + if err != nil { + return 0 + } + return parsed + } + return 0 +} + // Float64Flag is a flag with type float64 type Float64Flag struct { Name string @@ -146,6 +186,18 @@ func (c *Context) GlobalFloat64(name string) float64 { return 0 } +func lookupFloat64(name string, set *flag.FlagSet) float64 { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseFloat(f.Value.String(), 64) + if err != nil { + return 0 + } + return parsed + } + return 0 +} + // GenericFlag is a flag with type Generic type GenericFlag struct { Name string @@ -181,6 +233,18 @@ func (c *Context) GlobalGeneric(name string) interface{} { return nil } +func lookupGeneric(name string, set *flag.FlagSet) interface{} { + f := set.Lookup(name) + if f != nil { + parsed, err := f.Value, error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} + // Int64Flag is a flag with type int64 type Int64Flag struct { Name string @@ -217,6 +281,18 @@ func (c *Context) GlobalInt64(name string) int64 { return 0 } +func lookupInt64(name string, set *flag.FlagSet) int64 { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return parsed + } + return 0 +} + // IntFlag is a flag with type int type IntFlag struct { Name string @@ -253,6 +329,18 @@ func (c *Context) GlobalInt(name string) int { return 0 } +func lookupInt(name string, set *flag.FlagSet) int { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return int(parsed) + } + return 0 +} + // IntSliceFlag is a flag with type *IntSlice type IntSliceFlag struct { Name string @@ -288,6 +376,18 @@ func (c *Context) GlobalIntSlice(name string) []int { return nil } +func lookupIntSlice(name string, set *flag.FlagSet) []int { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} + // Int64SliceFlag is a flag with type *Int64Slice type Int64SliceFlag struct { Name string @@ -323,6 +423,18 @@ func (c *Context) GlobalInt64Slice(name string) []int64 { return nil } +func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} + // StringFlag is a flag with type string type StringFlag struct { Name string @@ -359,6 +471,18 @@ func (c *Context) GlobalString(name string) string { return "" } +func lookupString(name string, set *flag.FlagSet) string { + f := set.Lookup(name) + if f != nil { + parsed, err := f.Value.String(), error(nil) + if err != nil { + return "" + } + return parsed + } + return "" +} + // StringSliceFlag is a flag with type *StringSlice type StringSliceFlag struct { Name string @@ -394,6 +518,18 @@ func (c *Context) GlobalStringSlice(name string) []string { return nil } +func lookupStringSlice(name string, set *flag.FlagSet) []string { + f := set.Lookup(name) + if f != nil { + parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) + if err != nil { + return nil + } + return parsed + } + return nil +} + // Uint64Flag is a flag with type uint64 type Uint64Flag struct { Name string @@ -430,6 +566,18 @@ func (c *Context) GlobalUint64(name string) uint64 { return 0 } +func lookupUint64(name string, set *flag.FlagSet) uint64 { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return parsed + } + return 0 +} + // UintFlag is a flag with type uint type UintFlag struct { Name string @@ -465,3 +613,15 @@ func (c *Context) GlobalUint(name string) uint { } return 0 } + +func lookupUint(name string, set *flag.FlagSet) uint { + f := set.Lookup(name) + if f != nil { + parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return uint(parsed) + } + return 0 +} diff --git a/generate-flag-types b/generate-flag-types index fc25349..9bf0998 100755 --- a/generate-flag-types +++ b/generate-flag-types @@ -27,7 +27,9 @@ definition keys is: "dest": false, "doctail": " which really only wraps a []float64, oh well!", "context_type": "[]float64", - "context_default": "nil" + "context_default": "nil", + "parser": "parseVeryMuchType(f.Value.String())", + "parser_cast": "[]float64(parsed)" } The meaning of each field is as follows: @@ -45,7 +47,11 @@ The meaning of each field is as follows: context_default (string) - The literal value used as the default by the `*cli.Context` reader funcs when no value is present - + parser (string) - Literal code used to parse the flag `f`, + expected to have a return signature of + (value, error) + parser_cast (string) - Literal code used to cast the `parsed` value + returned from the `parser` code """ from __future__ import print_function, unicode_literals @@ -116,6 +122,9 @@ def _write_flag_types(outfile, types): typedef.setdefault('context_type', typedef['type']) typedef.setdefault('dest', True) typedef.setdefault('value', True) + typedef.setdefault('parser', 'f.Value, error(nil)') + typedef.setdefault('parser_cast', 'parsed') + _fwrite(outfile, """\ // {name}Flag is a flag with type {type}{doctail} @@ -165,6 +174,17 @@ def _write_flag_types(outfile, types): return {context_default} }} + func lookup{name}(name string, set *flag.FlagSet) {context_type} {{ + f := set.Lookup(name) + if f != nil {{ + parsed, err := {parser} + if err != nil {{ + return {context_default} + }} + return {parser_cast} + }} + return {context_default} + }} """.format(**typedef)) From c3b03b8437db746cd0b1bcf48dbea12b0c8f4484 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Mon, 11 Jul 2016 06:01:08 -0400 Subject: [PATCH 09/10] Adding flag type generation for altsrc and a mention of this whole thing in the change log --- CHANGELOG.md | 2 + altsrc/altsrc.go | 3 + altsrc/flag.go | 176 --------------------------- altsrc/flag_generated.go | 256 +++++++++++++++++++++++++++++++++++++++ cli.go | 2 +- generate-flag-types | 88 +++++++++++--- 6 files changed, 330 insertions(+), 197 deletions(-) create mode 100644 altsrc/altsrc.go create mode 100644 altsrc/flag_generated.go diff --git a/CHANGELOG.md b/CHANGELOG.md index d1904fe..0f74c92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ **ATTN**: This project uses [semantic versioning](http://semver.org/). ## [Unreleased] +### Added +- Flag type code generation via `go generate` ## [1.18.0] - 2016-06-27 ### Added diff --git a/altsrc/altsrc.go b/altsrc/altsrc.go new file mode 100644 index 0000000..ac34bf6 --- /dev/null +++ b/altsrc/altsrc.go @@ -0,0 +1,3 @@ +package altsrc + +//go:generate python ../generate-flag-types altsrc -i ../flag-types.json -o flag_generated.go diff --git a/altsrc/flag.go b/altsrc/flag.go index 3e44d02..8add2fb 100644 --- a/altsrc/flag.go +++ b/altsrc/flag.go @@ -1,7 +1,6 @@ package altsrc import ( - "flag" "fmt" "os" "strconv" @@ -63,18 +62,6 @@ func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context } } -// GenericFlag is the flag type that wraps cli.GenericFlag to allow -// for other values to be specified -type GenericFlag struct { - cli.GenericFlag - set *flag.FlagSet -} - -// NewGenericFlag creates a new GenericFlag -func NewGenericFlag(flag cli.GenericFlag) *GenericFlag { - return &GenericFlag{GenericFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a generic value to the flagSet if required func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -94,25 +81,6 @@ func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourc return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped GenericFlag.Apply -func (f *GenericFlag) Apply(set *flag.FlagSet) { - f.set = set - f.GenericFlag.Apply(set) -} - -// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow -// for other values to be specified -type StringSliceFlag struct { - cli.StringSliceFlag - set *flag.FlagSet -} - -// NewStringSliceFlag creates a new StringSliceFlag -func NewStringSliceFlag(flag cli.StringSliceFlag) *StringSliceFlag { - return &StringSliceFlag{StringSliceFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a StringSlice value to the flagSet if required func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -135,25 +103,6 @@ func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputS return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped StringSliceFlag.Apply -func (f *StringSliceFlag) Apply(set *flag.FlagSet) { - f.set = set - f.StringSliceFlag.Apply(set) -} - -// IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow -// for other values to be specified -type IntSliceFlag struct { - cli.IntSliceFlag - set *flag.FlagSet -} - -// NewIntSliceFlag creates a new IntSliceFlag -func NewIntSliceFlag(flag cli.IntSliceFlag) *IntSliceFlag { - return &IntSliceFlag{IntSliceFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a IntSlice value if required func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -176,25 +125,6 @@ func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped IntSliceFlag.Apply -func (f *IntSliceFlag) Apply(set *flag.FlagSet) { - f.set = set - f.IntSliceFlag.Apply(set) -} - -// BoolFlag is the flag type that wraps cli.BoolFlag to allow -// for other values to be specified -type BoolFlag struct { - cli.BoolFlag - set *flag.FlagSet -} - -// NewBoolFlag creates a new BoolFlag -func NewBoolFlag(flag cli.BoolFlag) *BoolFlag { - return &BoolFlag{BoolFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a Bool value to the flagSet if required func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -213,25 +143,6 @@ func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped BoolFlag.Apply -func (f *BoolFlag) Apply(set *flag.FlagSet) { - f.set = set - f.BoolFlag.Apply(set) -} - -// BoolTFlag is the flag type that wraps cli.BoolTFlag to allow -// for other values to be specified -type BoolTFlag struct { - cli.BoolTFlag - set *flag.FlagSet -} - -// NewBoolTFlag creates a new BoolTFlag -func NewBoolTFlag(flag cli.BoolTFlag) *BoolTFlag { - return &BoolTFlag{BoolTFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a BoolT value to the flagSet if required func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -250,26 +161,6 @@ func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceC return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped BoolTFlag.Apply -func (f *BoolTFlag) Apply(set *flag.FlagSet) { - f.set = set - - f.BoolTFlag.Apply(set) -} - -// StringFlag is the flag type that wraps cli.StringFlag to allow -// for other values to be specified -type StringFlag struct { - cli.StringFlag - set *flag.FlagSet -} - -// NewStringFlag creates a new StringFlag -func NewStringFlag(flag cli.StringFlag) *StringFlag { - return &StringFlag{StringFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a String value to the flagSet if required func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -288,26 +179,6 @@ func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSource return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped StringFlag.Apply -func (f *StringFlag) Apply(set *flag.FlagSet) { - f.set = set - - f.StringFlag.Apply(set) -} - -// IntFlag is the flag type that wraps cli.IntFlag to allow -// for other values to be specified -type IntFlag struct { - cli.IntFlag - set *flag.FlagSet -} - -// NewIntFlag creates a new IntFlag -func NewIntFlag(flag cli.IntFlag) *IntFlag { - return &IntFlag{IntFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a int value to the flagSet if required func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -326,25 +197,6 @@ func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCon return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped IntFlag.Apply -func (f *IntFlag) Apply(set *flag.FlagSet) { - f.set = set - f.IntFlag.Apply(set) -} - -// DurationFlag is the flag type that wraps cli.DurationFlag to allow -// for other values to be specified -type DurationFlag struct { - cli.DurationFlag - set *flag.FlagSet -} - -// NewDurationFlag creates a new DurationFlag -func NewDurationFlag(flag cli.DurationFlag) *DurationFlag { - return &DurationFlag{DurationFlag: flag, set: nil} -} - // ApplyInputSourceValue applies a Duration value to the flagSet if required func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -363,26 +215,6 @@ func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped DurationFlag.Apply -func (f *DurationFlag) Apply(set *flag.FlagSet) { - f.set = set - - f.DurationFlag.Apply(set) -} - -// Float64Flag is the flag type that wraps cli.Float64Flag to allow -// for other values to be specified -type Float64Flag struct { - cli.Float64Flag - set *flag.FlagSet -} - -// NewFloat64Flag creates a new Float64Flag -func NewFloat64Flag(flag cli.Float64Flag) *Float64Flag { - return &Float64Flag{Float64Flag: flag, set: nil} -} - // ApplyInputSourceValue applies a Float64 value to the flagSet if required func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error { if f.set != nil { @@ -402,14 +234,6 @@ func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourc return nil } -// Apply saves the flagSet for later usage then calls -// the wrapped Float64Flag.Apply -func (f *Float64Flag) Apply(set *flag.FlagSet) { - f.set = set - - f.Float64Flag.Apply(set) -} - func isEnvVarSet(envVars string) bool { for _, envVar := range strings.Split(envVars, ",") { envVar = strings.TrimSpace(envVar) diff --git a/altsrc/flag_generated.go b/altsrc/flag_generated.go new file mode 100644 index 0000000..fa76724 --- /dev/null +++ b/altsrc/flag_generated.go @@ -0,0 +1,256 @@ +package altsrc + +import ( + "flag" + + "github.com/urfave/cli" +) + +// WARNING: This file is generated! + +// BoolFlag is the flag type that wraps cli.BoolFlag to allow +// for other values to be specified +type BoolFlag struct { + cli.BoolFlag + set *flag.FlagSet +} + +// NewBoolFlag creates a new BoolFlag +func NewBoolFlag(fl cli.BoolFlag) *BoolFlag { + return &BoolFlag{BoolFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped BoolFlag.Apply +func (f *BoolFlag) Apply(set *flag.FlagSet) { + f.set = set + f.BoolFlag.Apply(set) +} + +// BoolTFlag is the flag type that wraps cli.BoolTFlag to allow +// for other values to be specified +type BoolTFlag struct { + cli.BoolTFlag + set *flag.FlagSet +} + +// NewBoolTFlag creates a new BoolTFlag +func NewBoolTFlag(fl cli.BoolTFlag) *BoolTFlag { + return &BoolTFlag{BoolTFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped BoolTFlag.Apply +func (f *BoolTFlag) Apply(set *flag.FlagSet) { + f.set = set + f.BoolTFlag.Apply(set) +} + +// DurationFlag is the flag type that wraps cli.DurationFlag to allow +// for other values to be specified +type DurationFlag struct { + cli.DurationFlag + set *flag.FlagSet +} + +// NewDurationFlag creates a new DurationFlag +func NewDurationFlag(fl cli.DurationFlag) *DurationFlag { + return &DurationFlag{DurationFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped DurationFlag.Apply +func (f *DurationFlag) Apply(set *flag.FlagSet) { + f.set = set + f.DurationFlag.Apply(set) +} + +// Float64Flag is the flag type that wraps cli.Float64Flag to allow +// for other values to be specified +type Float64Flag struct { + cli.Float64Flag + set *flag.FlagSet +} + +// NewFloat64Flag creates a new Float64Flag +func NewFloat64Flag(fl cli.Float64Flag) *Float64Flag { + return &Float64Flag{Float64Flag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped Float64Flag.Apply +func (f *Float64Flag) Apply(set *flag.FlagSet) { + f.set = set + f.Float64Flag.Apply(set) +} + +// GenericFlag is the flag type that wraps cli.GenericFlag to allow +// for other values to be specified +type GenericFlag struct { + cli.GenericFlag + set *flag.FlagSet +} + +// NewGenericFlag creates a new GenericFlag +func NewGenericFlag(fl cli.GenericFlag) *GenericFlag { + return &GenericFlag{GenericFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped GenericFlag.Apply +func (f *GenericFlag) Apply(set *flag.FlagSet) { + f.set = set + f.GenericFlag.Apply(set) +} + +// Int64Flag is the flag type that wraps cli.Int64Flag to allow +// for other values to be specified +type Int64Flag struct { + cli.Int64Flag + set *flag.FlagSet +} + +// NewInt64Flag creates a new Int64Flag +func NewInt64Flag(fl cli.Int64Flag) *Int64Flag { + return &Int64Flag{Int64Flag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped Int64Flag.Apply +func (f *Int64Flag) Apply(set *flag.FlagSet) { + f.set = set + f.Int64Flag.Apply(set) +} + +// IntFlag is the flag type that wraps cli.IntFlag to allow +// for other values to be specified +type IntFlag struct { + cli.IntFlag + set *flag.FlagSet +} + +// NewIntFlag creates a new IntFlag +func NewIntFlag(fl cli.IntFlag) *IntFlag { + return &IntFlag{IntFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped IntFlag.Apply +func (f *IntFlag) Apply(set *flag.FlagSet) { + f.set = set + f.IntFlag.Apply(set) +} + +// IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow +// for other values to be specified +type IntSliceFlag struct { + cli.IntSliceFlag + set *flag.FlagSet +} + +// NewIntSliceFlag creates a new IntSliceFlag +func NewIntSliceFlag(fl cli.IntSliceFlag) *IntSliceFlag { + return &IntSliceFlag{IntSliceFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped IntSliceFlag.Apply +func (f *IntSliceFlag) Apply(set *flag.FlagSet) { + f.set = set + f.IntSliceFlag.Apply(set) +} + +// Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow +// for other values to be specified +type Int64SliceFlag struct { + cli.Int64SliceFlag + set *flag.FlagSet +} + +// NewInt64SliceFlag creates a new Int64SliceFlag +func NewInt64SliceFlag(fl cli.Int64SliceFlag) *Int64SliceFlag { + return &Int64SliceFlag{Int64SliceFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped Int64SliceFlag.Apply +func (f *Int64SliceFlag) Apply(set *flag.FlagSet) { + f.set = set + f.Int64SliceFlag.Apply(set) +} + +// StringFlag is the flag type that wraps cli.StringFlag to allow +// for other values to be specified +type StringFlag struct { + cli.StringFlag + set *flag.FlagSet +} + +// NewStringFlag creates a new StringFlag +func NewStringFlag(fl cli.StringFlag) *StringFlag { + return &StringFlag{StringFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped StringFlag.Apply +func (f *StringFlag) Apply(set *flag.FlagSet) { + f.set = set + f.StringFlag.Apply(set) +} + +// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow +// for other values to be specified +type StringSliceFlag struct { + cli.StringSliceFlag + set *flag.FlagSet +} + +// NewStringSliceFlag creates a new StringSliceFlag +func NewStringSliceFlag(fl cli.StringSliceFlag) *StringSliceFlag { + return &StringSliceFlag{StringSliceFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped StringSliceFlag.Apply +func (f *StringSliceFlag) Apply(set *flag.FlagSet) { + f.set = set + f.StringSliceFlag.Apply(set) +} + +// Uint64Flag is the flag type that wraps cli.Uint64Flag to allow +// for other values to be specified +type Uint64Flag struct { + cli.Uint64Flag + set *flag.FlagSet +} + +// NewUint64Flag creates a new Uint64Flag +func NewUint64Flag(fl cli.Uint64Flag) *Uint64Flag { + return &Uint64Flag{Uint64Flag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped Uint64Flag.Apply +func (f *Uint64Flag) Apply(set *flag.FlagSet) { + f.set = set + f.Uint64Flag.Apply(set) +} + +// UintFlag is the flag type that wraps cli.UintFlag to allow +// for other values to be specified +type UintFlag struct { + cli.UintFlag + set *flag.FlagSet +} + +// NewUintFlag creates a new UintFlag +func NewUintFlag(fl cli.UintFlag) *UintFlag { + return &UintFlag{UintFlag: fl, set: nil} +} + +// Apply saves the flagSet for later usage calls, then calls the +// wrapped UintFlag.Apply +func (f *UintFlag) Apply(set *flag.FlagSet) { + f.set = set + f.UintFlag.Apply(set) +} diff --git a/cli.go b/cli.go index 1247a84..74fd101 100644 --- a/cli.go +++ b/cli.go @@ -18,4 +18,4 @@ // } package cli -//go:generate python ./generate-flag-types -i flag-types.json -o flag_generated.go +//go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go diff --git a/generate-flag-types b/generate-flag-types index 9bf0998..e48e7fd 100755 --- a/generate-flag-types +++ b/generate-flag-types @@ -13,9 +13,9 @@ An example of the minimum definition needed is: "context_default": "nil" } -In this example, the generated code will include a type named `SomeTypeFlag` -that is expected to wrap a value of type `sometype`. Fetching values by name -via `*cli.Context` will default to a value of `nil`. +In this example, the code generated for the `cli` package will include a type +named `SomeTypeFlag` that is expected to wrap a value of type `sometype`. +Fetching values by name via `*cli.Context` will default to a value of `nil`. A more complete, albeit somewhat redundant, example showing all available definition keys is: @@ -36,12 +36,14 @@ The meaning of each field is as follows: name (string) - The type "name", which will be suffixed with `Flag` when generating the type definition - type (string) - The type that the generated `Flag` type is - expected to "contain" as its `.Value` member - value (bool) - Should the generated type have a `Value` member? - dest (bool) - Should the generated type support a destination - pointer? - doctail (string) - Additional docs for the flag type comment + for `cli` and the wrapper type for `altsrc` + type (string) - The type that the generated `Flag` type for `cli` + is expected to "contain" as its `.Value` member + value (bool) - Should the generated `cli` type have a `Value` + member? + dest (bool) - Should the generated `cli` type support a + destination pointer? + doctail (string) - Additional docs for the `cli` flag type comment context_type (string) - The literal type used in the `*cli.Context` reader func signature context_default (string) - The literal value used as the default by the @@ -74,6 +76,11 @@ def main(sysargs=sys.argv[:]): parser = argparse.ArgumentParser( description='Generate flag type code!', formatter_class=_FancyFormatter) + parser.add_argument( + 'package', + type=str, default='cli', choices=['cli', 'altsrc'], + help='Package for which flag types will be generated' + ) parser.add_argument( '-i', '--in-json', type=argparse.FileType('r'), @@ -89,15 +96,15 @@ def main(sysargs=sys.argv[:]): parser.epilog = __doc__ args = parser.parse_args(sysargs[1:]) - _generate_flag_types(args.out_go, args.in_json) + _generate_flag_types(_WRITEFUNCS[args.package], args.out_go, args.in_json) return 0 -def _generate_flag_types(output_go, input_json): +def _generate_flag_types(writefunc, output_go, input_json): types = json.load(input_json) tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False) - _write_flag_types(tmp, types) + writefunc(tmp, types) tmp.close() new_content = subprocess.check_output( @@ -109,7 +116,16 @@ def _generate_flag_types(output_go, input_json): os.remove(tmp.name) -def _write_flag_types(outfile, types): +def _set_typedef_defaults(typedef): + typedef.setdefault('doctail', '') + typedef.setdefault('context_type', typedef['type']) + typedef.setdefault('dest', True) + typedef.setdefault('value', True) + typedef.setdefault('parser', 'f.Value, error(nil)') + typedef.setdefault('parser_cast', 'parsed') + + +def _write_cli_flag_types(outfile, types): _fwrite(outfile, """\ package cli @@ -118,13 +134,7 @@ def _write_flag_types(outfile, types): """) for typedef in types: - typedef.setdefault('doctail', '') - typedef.setdefault('context_type', typedef['type']) - typedef.setdefault('dest', True) - typedef.setdefault('value', True) - typedef.setdefault('parser', 'f.Value, error(nil)') - typedef.setdefault('parser_cast', 'parsed') - + _set_typedef_defaults(typedef) _fwrite(outfile, """\ // {name}Flag is a flag with type {type}{doctail} @@ -188,9 +198,47 @@ def _write_flag_types(outfile, types): """.format(**typedef)) +def _write_altsrc_flag_types(outfile, types): + _fwrite(outfile, """\ + package altsrc + + // WARNING: This file is generated! + + """) + + for typedef in types: + _set_typedef_defaults(typedef) + + _fwrite(outfile, """\ + // {name}Flag is the flag type that wraps cli.{name}Flag to allow + // for other values to be specified + type {name}Flag struct {{ + cli.{name}Flag + set *flag.FlagSet + }} + + // New{name}Flag creates a new {name}Flag + func New{name}Flag(fl cli.{name}Flag) *{name}Flag {{ + return &{name}Flag{{{name}Flag: fl, set: nil}} + }} + + // Apply saves the flagSet for later usage calls, then calls the + // wrapped {name}Flag.Apply + func (f *{name}Flag) Apply(set *flag.FlagSet) {{ + f.set = set + f.{name}Flag.Apply(set) + }} + """.format(**typedef)) + + def _fwrite(outfile, text): print(textwrap.dedent(text), end='', file=outfile) +_WRITEFUNCS = { + 'cli': _write_cli_flag_types, + 'altsrc': _write_altsrc_flag_types +} + if __name__ == '__main__': sys.exit(main()) From 8d976fe182232580613656aab99fc64953eeba83 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Mon, 11 Jul 2016 06:02:15 -0400 Subject: [PATCH 10/10] Get package choices from source of truth --- generate-flag-types | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generate-flag-types b/generate-flag-types index e48e7fd..8567f5d 100755 --- a/generate-flag-types +++ b/generate-flag-types @@ -78,7 +78,7 @@ def main(sysargs=sys.argv[:]): formatter_class=_FancyFormatter) parser.add_argument( 'package', - type=str, default='cli', choices=['cli', 'altsrc'], + type=str, default='cli', choices=_WRITEFUNCS.keys(), help='Package for which flag types will be generated' ) parser.add_argument(