1package cli 2 3import ( 4 "flag" 5 "fmt" 6) 7 8// Generic is a generic parseable type identified by a specific flag 9type Generic interface { 10 Set(value string) error 11 String() string 12} 13 14// GenericFlag is a flag with type Generic 15type GenericFlag struct { 16 Name string 17 Usage string 18 EnvVar string 19 FilePath string 20 Required bool 21 Hidden bool 22 TakesFile bool 23 Value Generic 24} 25 26// String returns a readable representation of this value 27// (for usage defaults) 28func (f GenericFlag) String() string { 29 return FlagStringer(f) 30} 31 32// GetName returns the name of the flag 33func (f GenericFlag) GetName() string { 34 return f.Name 35} 36 37// IsRequired returns whether or not the flag is required 38func (f GenericFlag) IsRequired() bool { 39 return f.Required 40} 41 42// TakesValue returns true of the flag takes a value, otherwise false 43func (f GenericFlag) TakesValue() bool { 44 return true 45} 46 47// GetUsage returns the usage string for the flag 48func (f GenericFlag) GetUsage() string { 49 return f.Usage 50} 51 52// GetValue returns the flags value as string representation and an empty 53// string if the flag takes no value at all. 54func (f GenericFlag) GetValue() string { 55 if f.Value != nil { 56 return f.Value.String() 57 } 58 return "" 59} 60 61// Apply takes the flagset and calls Set on the generic flag with the value 62// provided by the user for parsing by the flag 63// Ignores parsing errors 64func (f GenericFlag) Apply(set *flag.FlagSet) { 65 _ = f.ApplyWithError(set) 66} 67 68// ApplyWithError takes the flagset and calls Set on the generic flag with the value 69// provided by the user for parsing by the flag 70func (f GenericFlag) ApplyWithError(set *flag.FlagSet) error { 71 val := f.Value 72 if fileEnvVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { 73 if err := val.Set(fileEnvVal); err != nil { 74 return fmt.Errorf("could not parse %s as value for flag %s: %s", fileEnvVal, f.Name, err) 75 } 76 } 77 78 eachName(f.Name, func(name string) { 79 set.Var(f.Value, name, f.Usage) 80 }) 81 82 return nil 83} 84 85// Generic looks up the value of a local GenericFlag, returns 86// nil if not found 87func (c *Context) Generic(name string) interface{} { 88 return lookupGeneric(name, c.flagSet) 89} 90 91// GlobalGeneric looks up the value of a global GenericFlag, returns 92// nil if not found 93func (c *Context) GlobalGeneric(name string) interface{} { 94 if fs := lookupGlobalFlagSet(name, c); fs != nil { 95 return lookupGeneric(name, fs) 96 } 97 return nil 98} 99 100func lookupGeneric(name string, set *flag.FlagSet) interface{} { 101 f := set.Lookup(name) 102 if f != nil { 103 parsed, err := f.Value, error(nil) 104 if err != nil { 105 return nil 106 } 107 return parsed 108 } 109 return nil 110} 111