Require configuration selectors only for applicable scopes

This commit is contained in:
2026-10-07 16:44:10 +00:00
parent 9f47c7d9bc
commit d8db15f74d
4 changed files with 61 additions and 7 deletions

View File

@@ -27,10 +27,15 @@ func configInputFlags[C any](suite ConfigSuite[C], formatDefault string) []Flag[
}
func adaptSelector[C any](selector Selector[C]) Flag[configInput[C]] {
return adaptContextSelector(selector,
flag := adaptContextSelector(selector,
func(input *configInput[C]) *C { return &input.SelectorContext },
func(input *configInput[C], state selectorState[C]) { input.selectors = append(input.selectors, state) },
)
if flag.binding.meta.Required {
flag.binding.meta.Required = false // Scope-aware preflight enforces this requirement.
flag.binding.meta.Usage += " (required where applicable)"
}
return flag
}
func adaptContextSelector[C any, I any](selector Selector[C], selectContext func(*I) *C, record func(*I, selectorState[C])) Flag[I] {
@@ -53,6 +58,8 @@ func adaptContextSelector[C any, I any](selector Selector[C], selectContext func
return nil, err
}
state := selectorState[C]{
name: binding.meta.Name,
required: binding.meta.Required,
scopes: append([]string(nil), selector.Scopes...),
supplied: len(values) > 0,
apply: apply,
@@ -128,9 +135,6 @@ func selectConfigScopes[C any](suite ConfigSuite[C], input configInput[C], opera
}
}
for _, selector := range input.selectors {
if !selector.supplied {
continue
}
applies := false
for _, scopeName := range scopes {
if selectorApplies(selector.scopes, scopeName) {
@@ -138,7 +142,10 @@ func selectConfigScopes[C any](suite ConfigSuite[C], input configInput[C], opera
break
}
}
if !applies {
if applies && selector.required && !selector.supplied {
return nil, fmt.Errorf("required flag --%s was not supplied", selector.name)
}
if selector.supplied && !applies {
return nil, fmt.Errorf("selector is not applicable to configuration scope %q", input.Scope)
}
}