Only apply altsrc input source values when set

Closes #1373
This commit is contained in:
Dan Buch 2022-04-25 20:43:43 -04:00
parent e3aa8d3246
commit efe04493fc
Signed by: meatballhat
GPG Key ID: A12F782281063434
4 changed files with 101 additions and 100 deletions

View File

@ -64,16 +64,14 @@ func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *c
// ApplyInputSourceValue applies a generic value to the flagSet if required // ApplyInputSourceValue applies a generic value to the flagSet if required
func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.IsSet(f.GenericFlag.Name) {
if !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { value, err := isc.Generic(f.GenericFlag.Name)
value, err := isc.Generic(f.GenericFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value != nil {
if value != nil { for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, value.String())
_ = f.set.Set(name, value.String())
}
} }
} }
} }
@ -83,19 +81,17 @@ func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCo
// ApplyInputSourceValue applies a StringSlice value to the flagSet if required // ApplyInputSourceValue applies a StringSlice value to the flagSet if required
func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.IsSet(f.StringSliceFlag.Name) {
if !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { value, err := isc.StringSlice(f.StringSliceFlag.Name)
value, err := isc.StringSlice(f.StringSliceFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value != nil {
if value != nil { var sliceValue cli.StringSlice = *(cli.NewStringSlice(value...))
var sliceValue cli.StringSlice = *(cli.NewStringSlice(value...)) for _, name := range f.Names() {
for _, name := range f.Names() { underlyingFlag := f.set.Lookup(name)
underlyingFlag := f.set.Lookup(name) if underlyingFlag != nil {
if underlyingFlag != nil { underlyingFlag.Value = &sliceValue
underlyingFlag.Value = &sliceValue
}
} }
} }
} }
@ -105,19 +101,17 @@ func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSour
// ApplyInputSourceValue applies a IntSlice value if required // ApplyInputSourceValue applies a IntSlice value if required
func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.IsSet(f.IntSliceFlag.Name) {
if !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { value, err := isc.IntSlice(f.IntSliceFlag.Name)
value, err := isc.IntSlice(f.IntSliceFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value != nil {
if value != nil { var sliceValue cli.IntSlice = *(cli.NewIntSlice(value...))
var sliceValue cli.IntSlice = *(cli.NewIntSlice(value...)) for _, name := range f.Names() {
for _, name := range f.Names() { underlyingFlag := f.set.Lookup(name)
underlyingFlag := f.set.Lookup(name) if underlyingFlag != nil {
if underlyingFlag != nil { underlyingFlag.Value = &sliceValue
underlyingFlag.Value = &sliceValue
}
} }
} }
} }
@ -127,16 +121,14 @@ func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC
// ApplyInputSourceValue applies a Bool value to the flagSet if required // ApplyInputSourceValue applies a Bool value to the flagSet if required
func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) && isc.IsSet(f.BoolFlag.Name) {
if !cCtx.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) { value, err := isc.Bool(f.BoolFlag.Name)
value, err := isc.Bool(f.BoolFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value {
if value { for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, strconv.FormatBool(value))
_ = f.set.Set(name, strconv.FormatBool(value))
}
} }
} }
} }
@ -145,16 +137,14 @@ func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte
// ApplyInputSourceValue applies a String value to the flagSet if required // ApplyInputSourceValue applies a String value to the flagSet if required
func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.IsSet(f.StringFlag.Name) {
if !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.String(f.StringFlag.Name)
value, err := isc.String(f.StringFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value != "" {
if value != "" { for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, value)
_ = f.set.Set(name, value)
}
} }
} }
} }
@ -163,26 +153,24 @@ func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceCon
// ApplyInputSourceValue applies a Path value to the flagSet if required // ApplyInputSourceValue applies a Path value to the flagSet if required
func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.IsSet(f.PathFlag.Name) {
if !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.String(f.PathFlag.Name)
value, err := isc.String(f.PathFlag.Name) if err != nil {
if err != nil { return err
return err }
} if value != "" {
if value != "" { for _, name := range f.Names() {
for _, name := range f.Names() {
if !filepath.IsAbs(value) && isc.Source() != "" { if !filepath.IsAbs(value) && isc.Source() != "" {
basePathAbs, err := filepath.Abs(isc.Source()) basePathAbs, err := filepath.Abs(isc.Source())
if err != nil { if err != nil {
return err return err
}
value = filepath.Join(filepath.Dir(basePathAbs), value)
} }
_ = f.set.Set(name, value) value = filepath.Join(filepath.Dir(basePathAbs), value)
} }
_ = f.set.Set(name, value)
} }
} }
} }
@ -191,15 +179,13 @@ func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceConte
// ApplyInputSourceValue applies a int value to the flagSet if required // ApplyInputSourceValue applies a int value to the flagSet if required
func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.IsSet(f.IntFlag.Name) {
if !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.Int(f.IntFlag.Name)
value, err := isc.Int(f.IntFlag.Name) if err != nil {
if err != nil { return err
return err }
} for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, strconv.FormatInt(int64(value), 10))
_ = f.set.Set(name, strconv.FormatInt(int64(value), 10))
}
} }
} }
return nil return nil
@ -207,15 +193,13 @@ func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContex
// ApplyInputSourceValue applies a Duration value to the flagSet if required // ApplyInputSourceValue applies a Duration value to the flagSet if required
func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.IsSet(f.DurationFlag.Name) {
if !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.Duration(f.DurationFlag.Name)
value, err := isc.Duration(f.DurationFlag.Name) if err != nil {
if err != nil { return err
return err }
} for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, value.String())
_ = f.set.Set(name, value.String())
}
} }
} }
return nil return nil
@ -223,16 +207,14 @@ func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceC
// ApplyInputSourceValue applies a Float64 value to the flagSet if required // ApplyInputSourceValue applies a Float64 value to the flagSet if required
func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error {
if f.set != nil { if f.set != nil && !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) && isc.IsSet(f.Float64Flag.Name) {
if !(cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) { value, err := isc.Float64(f.Float64Flag.Name)
value, err := isc.Float64(f.Float64Flag.Name) if err != nil {
if err != nil { return err
return err }
} floatStr := float64ToString(value)
floatStr := float64ToString(value) for _, name := range f.Names() {
for _, name := range f.Names() { _ = f.set.Set(name, floatStr)
_ = f.set.Set(name, floatStr)
}
} }
} }
return nil return nil

View File

@ -14,6 +14,7 @@ import (
type InputSourceContext interface { type InputSourceContext interface {
Source() string Source() string
IsSet(name string) bool
Int(name string) (int, error) Int(name string) (int, error)
Duration(name string) (time.Duration, error) Duration(name string) (time.Duration, error)
Float64(name string) (float64, error) Float64(name string) (float64, error)

View File

@ -184,6 +184,11 @@ func (x *jsonSource) Bool(name string) (bool, error) {
return v, nil return v, nil
} }
func (x *jsonSource) IsSet(name string) bool {
_, err := x.getValue(name)
return err == nil
}
func (x *jsonSource) getValue(key string) (interface{}, error) { func (x *jsonSource) getValue(key string) (interface{}, error) {
return jsonGetValue(key, x.deserialized) return jsonGetValue(key, x.deserialized)
} }

View File

@ -244,6 +244,19 @@ func (fsm *MapInputSource) Bool(name string) (bool, error) {
return false, nil return false, nil
} }
// IsSet returns the truth of the key's existence in the map
func (fsm *MapInputSource) IsSet(name string) bool {
if _, exists := fsm.valueMap[name]; exists {
return exists
}
if _, exists := nestedVal(name, fsm.valueMap); exists {
return exists
}
return false
}
func incorrectTypeForFlagError(name, expectedTypeName string, value interface{}) error { func incorrectTypeForFlagError(name, expectedTypeName string, value interface{}) error {
valueType := reflect.TypeOf(value) valueType := reflect.TypeOf(value)
valueTypeName := "" valueTypeName := ""