Starting to hack in some env var configuration goodness
This commit is contained in:
parent
5ddbbe33e5
commit
97fd93272f
161
flag.go
161
flag.go
@ -3,18 +3,19 @@ package cli
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This flag enables bash-completion for all commands and subcommands
|
// 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
|
// 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
|
// 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.
|
// Flag is a common interface related to parsing flags in cli.
|
||||||
// For more advanced flag parsing techniques, it is recomended that
|
// 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
|
// GenericFlag is the flag type for types implementing Generic
|
||||||
type GenericFlag struct {
|
type GenericFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value Generic
|
Value Generic
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f GenericFlag) String() 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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Var(f.Value, name, f.Usage)
|
set.Var(f.Value, name, f.Usage)
|
||||||
})
|
})
|
||||||
@ -86,18 +95,29 @@ func (f *StringSlice) Value() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StringSliceFlag struct {
|
type StringSliceFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value *StringSlice
|
Value *StringSlice
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f StringSliceFlag) String() string {
|
func (f StringSliceFlag) String() string {
|
||||||
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
|
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
|
||||||
pref := prefixFor(firstName)
|
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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Var(f.Value, name, f.Usage)
|
set.Var(f.Value, name, f.Usage)
|
||||||
})
|
})
|
||||||
@ -129,18 +149,32 @@ func (f *IntSlice) Value() []int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IntSliceFlag struct {
|
type IntSliceFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value *IntSlice
|
Value *IntSlice
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f IntSliceFlag) String() string {
|
func (f IntSliceFlag) String() string {
|
||||||
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
|
firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ")
|
||||||
pref := prefixFor(firstName)
|
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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Var(f.Value, name, f.Usage)
|
set.Var(f.Value, name, f.Usage)
|
||||||
})
|
})
|
||||||
@ -151,17 +185,28 @@ func (f IntSliceFlag) getName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BoolFlag struct {
|
type BoolFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f BoolFlag) String() 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) {
|
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) {
|
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 {
|
type BoolTFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f BoolTFlag) String() 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) {
|
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) {
|
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 {
|
type StringFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value string
|
Value string
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f StringFlag) String() string {
|
func (f StringFlag) String() string {
|
||||||
@ -204,10 +261,16 @@ func (f StringFlag) String() string {
|
|||||||
fmtString = "%s %v\t%v"
|
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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.String(name, f.Value, f.Usage)
|
set.String(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
@ -218,16 +281,26 @@ func (f StringFlag) getName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IntFlag struct {
|
type IntFlag struct {
|
||||||
Name string
|
Name string
|
||||||
Value int
|
Value int
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f IntFlag) String() 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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Int(name, f.Value, f.Usage)
|
set.Int(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
@ -238,16 +311,26 @@ func (f IntFlag) getName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Float64Flag struct {
|
type Float64Flag struct {
|
||||||
Name string
|
Name string
|
||||||
Value float64
|
Value float64
|
||||||
Usage string
|
Usage string
|
||||||
|
EnvVar string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Float64Flag) String() 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) {
|
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) {
|
eachName(f.Name, func(name string) {
|
||||||
set.Float64(name, f.Value, f.Usage)
|
set.Float64(name, f.Value, f.Usage)
|
||||||
})
|
})
|
||||||
@ -278,3 +361,11 @@ func prefixedNames(fullName string) (prefixed string) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withEnvHint(envVar, str string) string {
|
||||||
|
envText := ""
|
||||||
|
if envVar != "" {
|
||||||
|
envText = fmt.Sprintf(" [$%s]", envVar)
|
||||||
|
}
|
||||||
|
return str + envText
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user