Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworking value source API #1760

Merged
merged 10 commits into from
Jun 19, 2023
2 changes: 1 addition & 1 deletion command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func buildExtendedTestCommand() *Command {
Name: "another-flag",
Aliases: []string{"b"},
Usage: "another usage text",
Sources: ValueSources{EnvSource("EXAMPLE_VARIABLE_NAME")},
Sources: EnvVars("EXAMPLE_VARIABLE_NAME"),
},
&BoolFlag{
Name: "hidden-flag",
Expand Down
9 changes: 5 additions & 4 deletions flag_bool_with_inverse.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (parent *BoolWithInverseFlag) initialize() {
parent.negativeFlag = &BoolFlag{
Category: child.Category,
DefaultText: child.DefaultText,
Sources: append(ValueSources{}, child.Sources...),
Sources: ValueSourceChain{Chain: append([]ValueSource{}, child.Sources.Chain...)},
Usage: child.Usage,
Required: child.Required,
Hidden: child.Hidden,
Expand All @@ -108,10 +108,11 @@ func (parent *BoolWithInverseFlag) initialize() {
parent.negativeFlag.Name = parent.inverseName()
parent.negativeFlag.Aliases = parent.inverseAliases()

if len(child.Sources) > 0 {
parent.negativeFlag.Sources = make(ValueSources, len(child.Sources))
if len(child.Sources.Chain) > 0 {
parent.negativeFlag.Sources = ValueSourceChain{Chain: make([]ValueSource, len(child.Sources.Chain))}

for idx, envVar := range child.GetEnvVars() {
parent.negativeFlag.Sources[idx] = EnvSource(strings.ToUpper(parent.InversePrefix) + envVar)
parent.negativeFlag.Sources.Chain[idx] = &envVarValueSource{Key: strings.ToUpper(parent.InversePrefix) + envVar}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion flag_bool_with_inverse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func TestBoolWithInverseEnvVars(t *testing.T) {
return &BoolWithInverseFlag{
BoolFlag: &BoolFlag{
Name: "env",
Sources: ValueSources{EnvSource("ENV")},
Sources: EnvVars("ENV"),
},
}
}
Expand Down
26 changes: 17 additions & 9 deletions flag_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct {
DefaultText string // default text of the flag for usage purposes
Usage string // usage string for help output

Sources ValueSources // sources to load flag value from
Sources ValueSourceChain // sources to load flag value from

Required bool // whether the flag is required or not
Hidden bool // whether to hide the flag in help output
Expand Down Expand Up @@ -132,16 +132,22 @@ func (f *FlagBase[T, C, V]) Apply(set *flag.FlagSet) error {
if !f.applied || !f.Persistent {
newVal := f.Value

if val, source, found := f.Sources.Get(); found {
if val, source, found := f.Sources.LookupWithSource(); found {
tmpVal := f.creator.Create(f.Value, new(T), f.Config)
if val != "" || reflect.TypeOf(f.Value).Kind() == reflect.String {
if err := tmpVal.Set(val); err != nil {
return fmt.Errorf("could not parse %q as %T value from %s for flag %s: %s", val, f.Value, source, f.Name, err)
return fmt.Errorf(
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
val, f.Value, source, f.Name, err,
)
}
} else if val == "" && reflect.TypeOf(f.Value).Kind() == reflect.Bool {
val = "false"
if err := tmpVal.Set(val); err != nil {
return fmt.Errorf("could not parse %q as %T value from %s for flag %s: %s", val, f.Value, source, f.Name, err)
return fmt.Errorf(
"could not parse %[1]q as %[2]T value from %[3]s for flag %[4]s: %[5]s",
val, f.Value, source, f.Name, err,
)
}
}

Expand Down Expand Up @@ -206,13 +212,15 @@ func (f *FlagBase[T, C, V]) GetUsage() string {

// GetEnvVars returns the env vars for this flag
func (f *FlagBase[T, C, V]) GetEnvVars() []string {
var envs []string
for _, src := range f.Sources {
if esrc, ok := src.(EnvSource); ok {
envs = append(envs, string(esrc))
vals := []string{}

for _, src := range f.Sources.Chain {
if v, ok := src.(*envVarValueSource); ok {
vals = append(vals, v.Key)
}
}
return envs

return vals
}

// TakesValue returns true if the flag takes a value, otherwise false
Expand Down
Loading