Prepare both configuration comparison inputs

This commit is contained in:
2026-10-11 21:43:30 +00:00
parent d1591463ee
commit d2434b9580
4 changed files with 414 additions and 33 deletions

View File

@@ -23,14 +23,20 @@ type selectedScopeInput[I, S any] struct {
input I
}
type preparedComparison[I, S any] struct {
scope *preparedScope[I, S]
request ComparisonRequest[I]
}
type configOperationPlan[I, S any] struct {
prepared *preparedSuite[I, S]
operation Operation
selection Selection
scopeName string
format string
path configkit.Path
scopes []selectedScopeInput[I, S]
prepared *preparedSuite[I, S]
operation Operation
selection Selection
scopeName string
format string
path configkit.Path
scopes []selectedScopeInput[I, S]
comparison *preparedComparison[I, S]
}
func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operation Operation) commandkit.Command {
@@ -171,30 +177,54 @@ func prepareConfigOperation[I, S any](prepared *preparedSuite[I, S], operation O
}
if operation == Diff {
input.against = inheritComparisonSelection(input.selection, input.against)
scope := selected[0]
left, err := prepareScopeInput(prepared, input.values, scope, input.selection)
if err != nil {
return fmt.Errorf("configuration scope %q left input: %w", scope.scope.Name, err)
}
right, err := prepareScopeInput(prepared, input.values, scope, input.against)
if err != nil {
return fmt.Errorf("configuration scope %q right input: %w", scope.scope.Name, err)
}
plan.comparison = &preparedComparison[I, S]{
scope: scope,
request: ComparisonRequest[I]{
Left: ComparisonSide[I]{Selection: input.selection, Input: left},
Right: ComparisonSide[I]{Selection: input.against, Input: right},
},
}
input.plan = plan
return nil
}
for _, scope := range selected {
var value I
if prepared.newInput != nil {
value = prepared.newInput()
}
// Availability was checked above, so every binding for this scope
// belongs to the operation's captured union.
if err := input.values.ApplyTo(&value, scope.bindings...); err != nil {
value, err := prepareScopeInput(prepared, input.values, scope, input.selection)
if err != nil {
return fmt.Errorf("configuration scope %q: %w", scope.scope.Name, err)
}
if prepared.checkInput != nil {
if err := prepared.checkInput(scope.scope.Name, input.selection, value); err != nil {
return fmt.Errorf("configuration scope %q: %w", scope.scope.Name, err)
}
}
plan.scopes = append(plan.scopes, selectedScopeInput[I, S]{scope: scope, input: value})
}
input.plan = plan
return nil
}
func prepareScopeInput[I, S any](prepared *preparedSuite[I, S], values commandkit.FlagValues[I], scope *preparedScope[I, S], selection Selection) (I, error) {
var value I
if prepared.newInput != nil {
value = prepared.newInput()
}
// Availability was checked before this helper, so every binding for the
// selected scope belongs to the operation's captured union.
if err := values.ApplyTo(&value, scope.bindings...); err != nil {
return value, err
}
if prepared.checkInput != nil {
if err := prepared.checkInput(scope.scope.Name, selection, value); err != nil {
return value, err
}
}
return value, nil
}
func inheritComparisonSelection(left, right Selection) Selection {
if !right.Config.Set {
right.Config = left.Config