Merge remote-tracking branch 'origin/v1' into merging-from-v1
This commit is contained in:
130
flag.go
130
flag.go
@@ -4,12 +4,12 @@ import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -88,13 +88,29 @@ type Flag interface {
|
||||
Names() []string
|
||||
}
|
||||
|
||||
func flagSet(name string, flags []Flag) *flag.FlagSet {
|
||||
// errorableFlag is an interface that allows us to return errors during apply
|
||||
// it allows flags defined in this library to return errors in a fashion backwards compatible
|
||||
// TODO remove in v2 and modify the existing Flag interface to return errors
|
||||
type errorableFlag interface {
|
||||
Flag
|
||||
|
||||
ApplyWithError(*flag.FlagSet) error
|
||||
}
|
||||
|
||||
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
||||
set := flag.NewFlagSet(name, flag.ContinueOnError)
|
||||
|
||||
for _, f := range flags {
|
||||
f.Apply(set)
|
||||
//TODO remove in v2 when errorableFlag is removed
|
||||
if ef, ok := f.(errorableFlag); ok {
|
||||
if err := ef.ApplyWithError(set); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
f.Apply(set)
|
||||
}
|
||||
}
|
||||
return set
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// Generic is a generic parseable type identified by a specific flag
|
||||
@@ -109,7 +125,7 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) {
|
||||
val := f.Value
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
val.Set(envVal)
|
||||
break
|
||||
}
|
||||
@@ -166,15 +182,22 @@ func (f *StringSlice) Value() []string {
|
||||
return f.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of strings set by this flag
|
||||
func (f *StringSlice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
newVal := NewStringSlice()
|
||||
for _, s := range strings.Split(envVal, ",") {
|
||||
s = strings.TrimSpace(s)
|
||||
newVal.Set(s)
|
||||
if err := newVal.Set(s); err != nil {
|
||||
return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
}
|
||||
f.Value = newVal
|
||||
break
|
||||
@@ -256,17 +279,21 @@ func (i *IntSlice) Value() []int {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (f *IntSlice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
newVal := NewIntSlice()
|
||||
for _, s := range strings.Split(envVal, ",") {
|
||||
s = strings.TrimSpace(s)
|
||||
err := newVal.Set(s)
|
||||
if err != nil {
|
||||
fmt.Fprintf(ErrWriter, err.Error())
|
||||
if err := newVal.Set(s); err != nil {
|
||||
return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
}
|
||||
f.Value = newVal
|
||||
@@ -329,17 +356,21 @@ func (f *Int64Slice) Value() []int64 {
|
||||
return f.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (f *Int64Slice) Get() interface{} {
|
||||
return *f
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
newVal := NewInt64Slice()
|
||||
for _, s := range strings.Split(envVal, ",") {
|
||||
s = strings.TrimSpace(s)
|
||||
err := newVal.Set(s)
|
||||
if err != nil {
|
||||
fmt.Fprintf(ErrWriter, err.Error())
|
||||
if err := newVal.Set(s); err != nil {
|
||||
return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
}
|
||||
f.Value = newVal
|
||||
@@ -361,11 +392,13 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValBool, err := strconv.ParseBool(envVal)
|
||||
if err == nil {
|
||||
f.Value = envValBool
|
||||
}
|
||||
|
||||
val = envValBool
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -384,7 +417,7 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *StringFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
f.Value = envVal
|
||||
break
|
||||
}
|
||||
@@ -404,12 +437,13 @@ func (f *StringFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *IntFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValInt, err := strconv.ParseInt(envVal, 0, 64)
|
||||
if err == nil {
|
||||
f.Value = int(envValInt)
|
||||
break
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
f.Value = int(envValInt)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,12 +461,14 @@ func (f *IntFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *Int64Flag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValInt, err := strconv.ParseInt(envVal, 0, 64)
|
||||
if err == nil {
|
||||
f.Value = envValInt
|
||||
break
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = envValInt
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -450,12 +486,14 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) {
|
||||
func (f *UintFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValInt, err := strconv.ParseUint(envVal, 0, 64)
|
||||
if err == nil {
|
||||
f.Value = uint(envValInt)
|
||||
break
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = uint(envValInt)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,12 +511,14 @@ func (f *UintFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValInt, err := strconv.ParseUint(envVal, 0, 64)
|
||||
if err == nil {
|
||||
f.Value = uint64(envValInt)
|
||||
break
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = uint64(envValInt)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,12 +536,14 @@ func (f *Uint64Flag) Apply(set *flag.FlagSet) {
|
||||
func (f *DurationFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValDuration, err := time.ParseDuration(envVal)
|
||||
if err == nil {
|
||||
f.Value = envValDuration
|
||||
break
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = envValDuration
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,11 +561,14 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) {
|
||||
func (f *Float64Flag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
envValFloat, err := strconv.ParseFloat(envVal, 10)
|
||||
if err == nil {
|
||||
f.Value = float64(envValFloat)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = float64(envValFloat)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -591,7 +636,7 @@ func (f *Float64Slice) Value() []float64 {
|
||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) {
|
||||
if f.EnvVars != nil {
|
||||
for _, envVar := range f.EnvVars {
|
||||
if envVal := os.Getenv(envVar); envVal != "" {
|
||||
if envVal, ok := syscall.Getenv(envVar); ok {
|
||||
newVal := NewFloat64Slice()
|
||||
for _, s := range strings.Split(envVal, ",") {
|
||||
s = strings.TrimSpace(s)
|
||||
@@ -618,7 +663,8 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) {
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
visible := []Flag{}
|
||||
for _, flag := range fl {
|
||||
if !flagValue(flag).FieldByName("Hidden").Bool() {
|
||||
field := flagValue(flag).FieldByName("Hidden")
|
||||
if !field.IsValid() || !field.Bool() {
|
||||
visible = append(visible, flag)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user