Starting to hack in some env var configuration goodness

main
Dan Buch 10 years ago
parent 5ddbbe33e5
commit 97fd93272f

@ -3,18 +3,19 @@ package cli
import (
"flag"
"fmt"
"os"
"strconv"
"strings"
)
// This flag enables bash-completion for all commands and subcommands
var BashCompletionFlag = BoolFlag{"generate-bash-completion", ""}
var BashCompletionFlag = BoolFlag{"generate-bash-completion", "", ""}
// This flag prints the version for the application
var VersionFlag = BoolFlag{"version, v", "print the version"}
var VersionFlag = BoolFlag{"version, v", "print the version", ""}
// This flag prints the help for all commands and subcommands
var HelpFlag = BoolFlag{"help, h", "show help"}
var HelpFlag = BoolFlag{"help, h", "show help", ""}
// Flag is a common interface related to parsing flags in cli.
// For more advanced flag parsing techniques, it is recomended that
@ -51,16 +52,24 @@ type Generic interface {
// GenericFlag is the flag type for types implementing Generic
type GenericFlag struct {
Name string
Value Generic
Usage string
Name string
Value Generic
Usage string
EnvVar string
}
func (f GenericFlag) String() string {
return fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s%s %v\t`%v` %s", prefixFor(f.Name), f.Name, f.Value, "-"+f.Name+" option -"+f.Name+" option", f.Usage))
}
func (f GenericFlag) Apply(set *flag.FlagSet) {
val := f.Value
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
val.Set(envVal)
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
@ -86,18 +95,29 @@ func (f *StringSlice) Value() []string {
}
type StringSliceFlag struct {
Name string
Value *StringSlice
Usage string
Name string
Value *StringSlice
Usage string
EnvVar string
}
func (f StringSliceFlag) String() string {
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
pref := prefixFor(firstName)
return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
}
func (f StringSliceFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
newVal := &StringSlice{}
for _, s := range strings.Split(envVal, ",") {
newVal.Set(s)
}
f.Value = newVal
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
@ -129,18 +149,32 @@ func (f *IntSlice) Value() []int {
}
type IntSliceFlag struct {
Name string
Value *IntSlice
Usage string
Name string
Value *IntSlice
Usage string
EnvVar string
}
func (f IntSliceFlag) String() string {
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
pref := prefixFor(firstName)
return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), pref+firstName+" option "+pref+firstName+" option", f.Usage))
}
func (f IntSliceFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
newVal := &IntSlice{}
for _, s := range strings.Split(envVal, ",") {
err := newVal.Set(s)
if err != nil {
fmt.Fprintf(os.Stderr, err.Error())
}
}
f.Value = newVal
}
}
eachName(f.Name, func(name string) {
set.Var(f.Value, name, f.Usage)
})
@ -151,17 +185,28 @@ func (f IntSliceFlag) getName() string {
}
type BoolFlag struct {
Name string
Usage string
Name string
Usage string
EnvVar string
}
func (f BoolFlag) String() string {
return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
}
func (f BoolFlag) Apply(set *flag.FlagSet) {
val := false
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
envValBool, err := strconv.ParseBool(envVal)
if err == nil {
val = envValBool
}
}
}
eachName(f.Name, func(name string) {
set.Bool(name, false, f.Usage)
set.Bool(name, val, f.Usage)
})
}
@ -170,17 +215,28 @@ func (f BoolFlag) getName() string {
}
type BoolTFlag struct {
Name string
Usage string
Name string
Usage string
EnvVar string
}
func (f BoolTFlag) String() string {
return fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name), f.Usage))
}
func (f BoolTFlag) Apply(set *flag.FlagSet) {
val := true
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
envValBool, err := strconv.ParseBool(envVal)
if err == nil {
val = envValBool
}
}
}
eachName(f.Name, func(name string) {
set.Bool(name, true, f.Usage)
set.Bool(name, val, f.Usage)
})
}
@ -189,9 +245,10 @@ func (f BoolTFlag) getName() string {
}
type StringFlag struct {
Name string
Value string
Usage string
Name string
Value string
Usage string
EnvVar string
}
func (f StringFlag) String() string {
@ -204,10 +261,16 @@ func (f StringFlag) String() string {
fmtString = "%s %v\t%v"
}
return fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf(fmtString, prefixedNames(f.Name), f.Value, f.Usage))
}
func (f StringFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
f.Value = envVal
}
}
eachName(f.Name, func(name string) {
set.String(name, f.Value, f.Usage)
})
@ -218,16 +281,26 @@ func (f StringFlag) getName() string {
}
type IntFlag struct {
Name string
Value int
Usage string
Name string
Value int
Usage string
EnvVar string
}
func (f IntFlag) String() string {
return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage))
}
func (f IntFlag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
envValInt, err := strconv.ParseUint(envVal, 10, 64)
if err == nil {
f.Value = int(envValInt)
}
}
}
eachName(f.Name, func(name string) {
set.Int(name, f.Value, f.Usage)
})
@ -238,16 +311,26 @@ func (f IntFlag) getName() string {
}
type Float64Flag struct {
Name string
Value float64
Usage string
Name string
Value float64
Usage string
EnvVar string
}
func (f Float64Flag) String() string {
return fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage)
return withEnvHint(f.EnvVar, fmt.Sprintf("%s '%v'\t%v", prefixedNames(f.Name), f.Value, f.Usage))
}
func (f Float64Flag) Apply(set *flag.FlagSet) {
if f.EnvVar != "" {
if envVal := os.Getenv(f.EnvVar); envVal != "" {
envValFloat, err := strconv.ParseFloat(envVal, 10)
if err == nil {
f.Value = float64(envValFloat)
}
}
}
eachName(f.Name, func(name string) {
set.Float64(name, f.Value, f.Usage)
})
@ -278,3 +361,11 @@ func prefixedNames(fullName string) (prefixed string) {
}
return
}
func withEnvHint(envVar, str string) string {
envText := ""
if envVar != "" {
envText = fmt.Sprintf(" [$%s]", envVar)
}
return str + envText
}

Loading…
Cancel
Save