Add comparison selection and format flags

This commit is contained in:
2026-10-11 21:39:19 +00:00
parent 018f90a23c
commit d1591463ee
3 changed files with 229 additions and 6 deletions

View File

@@ -10,6 +10,7 @@ import (
type configCommandInput[I, S any] struct {
selection Selection
against Selection
scope commandkit.Supplied[string]
format commandkit.Supplied[string]
path commandkit.Supplied[string]
@@ -35,7 +36,7 @@ type configOperationPlan[I, S any] struct {
func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operation Operation) commandkit.Command {
defaultScope := "app"
defaultFormat := "text"
if operation == Show {
if operation == Show || operation == Diff {
defaultFormat = "yaml"
}
flags := []commandkit.Flag[*configCommandInput[I, S]]{
@@ -52,6 +53,18 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
(*input).selection.Overlay = value
}),
}
if operation == Diff {
flags = append(flags,
commandkit.ValueFlag(commandkit.FlagMeta{Name: "against-config", Usage: "Configuration source for the right side."}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
(*input).against.Config = value
}),
commandkit.ValueFlag(commandkit.FlagMeta{Name: "against-overlay", Usage: "Overlay source for the right side."}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
(*input).against.Overlay = value
}),
)
}
if operation == Explain {
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "path", Usage: "JSON Pointer path to explain.", Required: true}, (*string)(nil), parseConfigString,
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).path = value }))
@@ -90,6 +103,8 @@ func operationDeclaration(operation Operation) (string, string) {
return "sources", "List configuration sources."
case Explain:
return "explain", "Explain a configuration path."
case Diff:
return "diff", "Compare two configuration selections."
default:
return string(operation), "Inspect configuration."
}
@@ -103,6 +118,9 @@ func prepareConfigOperation[I, S any](prepared *preparedSuite[I, S], operation O
if operation == Show && format != "yaml" {
return fmt.Errorf("unsupported configuration show format %q", format)
}
if operation == Diff && format != "yaml" {
return fmt.Errorf("unsupported configuration diff format %q", format)
}
scopeName := "app"
if input.scope.Set {
@@ -151,6 +169,11 @@ func prepareConfigOperation[I, S any](prepared *preparedSuite[I, S], operation O
path: path,
scopes: make([]selectedScopeInput[I, S], 0, len(selected)),
}
if operation == Diff {
input.against = inheritComparisonSelection(input.selection, input.against)
input.plan = plan
return nil
}
for _, scope := range selected {
var value I
if prepared.newInput != nil {
@@ -172,6 +195,16 @@ func prepareConfigOperation[I, S any](prepared *preparedSuite[I, S], operation O
return nil
}
func inheritComparisonSelection(left, right Selection) Selection {
if !right.Config.Set {
right.Config = left.Config
}
if !right.Overlay.Set {
right.Overlay = left.Overlay
}
return right
}
func joinOperations(operations []Operation) string {
values := make([]string, len(operations))
for index, operation := range operations {