Document configuration comparison behavior
This commit is contained in:
@@ -24,9 +24,12 @@ app, err := commandkit.New(identity, ckconfig.AppCommand(loadAppConfig))
|
||||
|
||||
Use `ckconfig.Command(ckconfig.Suite[Input, State]{...})` to define named
|
||||
scopes, selectors, input checks, and state shared by the selected acquisitions
|
||||
in a config invocation. `ckconfig.FromConfigKit` adapts a typed ConfigKit loader.
|
||||
The `config` command family exposes scope discovery and the validate, show,
|
||||
sources, and explain operations supported by the declared scopes.
|
||||
or comparison in a config invocation. `ckconfig.FromConfigKit` adapts a typed
|
||||
ConfigKit loader. The `config` command family exposes scope discovery and the
|
||||
validate, show, sources, explain, and diff operations supported by the declared
|
||||
scopes. Comparison returns ConfigKit's native records to the YAML report path;
|
||||
the [CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections)
|
||||
owns its operator details.
|
||||
|
||||
The maintained [simple example](examples/simple) shows a complete consumer.
|
||||
The [CommandKit CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#configuration-scopes)
|
||||
|
||||
@@ -14,9 +14,10 @@ import (
|
||||
// FromConfigKit adapts a typed ConfigKit loader to all five native
|
||||
// configuration operations. The loader receives the operation's explicit
|
||||
// Selection, initialized input, and shared invocation state, and runs only when
|
||||
// an installed operation selects this scope. Construction and help do not call
|
||||
// it. A nil original loader is retained as a construction issue, even if callers
|
||||
// later narrow the scope's operation list.
|
||||
// an installed operation selects this scope. Comparison invokes it separately
|
||||
// for each reached side. Construction and help do not call it. A nil original
|
||||
// loader is retained as a construction issue, even if callers later narrow the
|
||||
// scope's operation list.
|
||||
func FromConfigKit[I, S, T any](
|
||||
name, summary string,
|
||||
load func(context.Context, Selection, I, S) (*configkit.Result[T], error),
|
||||
|
||||
@@ -17,7 +17,7 @@ type Selection struct {
|
||||
Overlay commandkit.Supplied[string]
|
||||
}
|
||||
|
||||
// Operation identifies a supported configuration inspection operation.
|
||||
// Operation identifies a supported standard configuration operation.
|
||||
type Operation string
|
||||
|
||||
const (
|
||||
@@ -42,7 +42,8 @@ type Request struct {
|
||||
}
|
||||
|
||||
// ComparisonSide groups one configuration selection with its independently
|
||||
// prepared typed input.
|
||||
// initialized and checked typed input. The supplied-state fields of Selection
|
||||
// are preserved for the scope's loader.
|
||||
type ComparisonSide[I any] struct {
|
||||
// Selection carries the explicit config and overlay inputs for this side.
|
||||
Selection Selection
|
||||
@@ -51,7 +52,8 @@ type ComparisonSide[I any] struct {
|
||||
}
|
||||
|
||||
// ComparisonRequest carries the earlier and later selections supplied to a
|
||||
// scope's comparison callback.
|
||||
// scope's comparison callback. Each side has a separately prepared input; the
|
||||
// callback receives shared invocation state separately.
|
||||
type ComparisonRequest[I any] struct {
|
||||
// Left is the earlier configuration selection.
|
||||
Left ComparisonSide[I]
|
||||
@@ -99,7 +101,9 @@ type Scope[I, S any] struct {
|
||||
// invocation.
|
||||
Acquire func(context.Context, Request, I, S) (commandkit.Acquired[View], error)
|
||||
// Compare compares two selections for this scope using one shared state.
|
||||
// It is required when Diff is declared in Operations.
|
||||
// Its Acquired result carries native difference records and diagnostics;
|
||||
// returned errors retain their supported cause identity. It is required when
|
||||
// Diff is declared in Operations.
|
||||
Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error)
|
||||
|
||||
issues []error
|
||||
@@ -116,24 +120,28 @@ type Selector[I any] struct {
|
||||
// Suite declares the typed input, shared state, selectors, and configuration
|
||||
// scopes used to assemble configuration commands.
|
||||
//
|
||||
// Input initialization is separate for each selected scope; state is shared
|
||||
// by that invocation's acquisitions. Factory results and callback effects remain
|
||||
// Input initialization is separate for each selected ordinary scope and each
|
||||
// reached comparison side; state is shared by the invocation's acquisitions or
|
||||
// comparison callback. Factory results and callback effects remain
|
||||
// caller-owned: Command does not deep-copy arbitrary objects or repair aliases
|
||||
// returned by factories. Core-owned repeated flag collections are copied when
|
||||
// applied to separate inputs. Factories are not invoked during construction,
|
||||
// installation, help, version, or scope discovery, and need not run after failure.
|
||||
type Suite[I, S any] struct {
|
||||
// NewInput is called once for each selected scope reached after operation
|
||||
// preflight, before applying its selectors and calling CheckInput.
|
||||
// NewInput is called once for each selected ordinary scope, or once for each
|
||||
// reached side of a comparison, after operation preflight and before applying
|
||||
// selectors and calling CheckInput.
|
||||
// If nil, input is the zero value of I, including nil for pointer types.
|
||||
NewInput func() I
|
||||
// NewState is called once when acquisition is reached, after all selected
|
||||
// inputs pass their checks. The result is shared by selected acquisitions.
|
||||
// NewState is called once when provider execution is reached, after all
|
||||
// selected inputs pass their checks. The result is shared by selected
|
||||
// acquisitions or the comparison callback.
|
||||
// If nil, state is the zero value of S, including nil for pointer types.
|
||||
NewState func() S
|
||||
// Selectors declares typed flags and their applicable scopes.
|
||||
Selectors []Selector[I]
|
||||
// CheckInput validates one initialized scope input after applicable values are applied.
|
||||
// CheckInput validates one initialized scope input after applicable values
|
||||
// are applied. Comparison sides are checked separately with their selection.
|
||||
CheckInput func(scope string, selection Selection, input I) error
|
||||
// Scopes declares the configuration scopes assembled by Command.
|
||||
Scopes []Scope[I, S]
|
||||
|
||||
@@ -43,9 +43,10 @@ type preparedSuite[I, S any] struct {
|
||||
// Command eagerly captures a configuration suite as a root-only config family.
|
||||
// It copies suite slices, retains callback references, and returns a reusable
|
||||
// declaration; installation does not invoke factories or providers. During an
|
||||
// inspection, it initializes input separately for each selected scope and
|
||||
// validates those inputs before acquisition. Suite documents factory timing,
|
||||
// zero values, shared state, and caller ownership of returned objects.
|
||||
// inspection, it initializes input separately for each selected scope. A
|
||||
// comparison initializes and checks both sides before creating shared state
|
||||
// and calling the pair provider. Suite documents factory timing, zero values,
|
||||
// shared state, and caller ownership of returned objects.
|
||||
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
|
||||
prepared := captureSuite(suite)
|
||||
if len(prepared.scopes) == 0 {
|
||||
@@ -67,7 +68,8 @@ func Command[I, S any](suite Suite[I, S]) commandkit.Command {
|
||||
|
||||
// AppCommand builds the state-free, input-free convenience suite for application
|
||||
// configuration. The application consumer supplies only its ConfigKit loader,
|
||||
// which runs only for a selected operation after input preflight.
|
||||
// which runs for ordinary operations and separately for each reached comparison
|
||||
// side after input preflight.
|
||||
func AppCommand[T any](load func(context.Context, Selection) (*configkit.Result[T], error)) commandkit.Command {
|
||||
var adapterLoad func(context.Context, Selection, struct{}, struct{}) (*configkit.Result[T], error)
|
||||
if load != nil {
|
||||
|
||||
Reference in New Issue
Block a user