Adopt ConfigKit module and APIs

This commit is contained in:
2026-11-04 14:58:20 +00:00
parent 1c778d7ad3
commit 2904eadf4f
21 changed files with 38 additions and 34 deletions

View File

@@ -1,6 +1,6 @@
# ConfigKit v1.1.0 adoption implementation plan # ConfigKit v1.1.0 adoption implementation plan
Status: planned; Stages 1–6 are not started. Status: Stage 1 complete; Stages 2–6 are not started.
This plan is for a Luna coding agent implementing the selected This plan is for a Luna coding agent implementing the selected
[ConfigKit adoption target](configkit-v1.1.0.md). Follow Stage 1 through Stage 6 [ConfigKit adoption target](configkit-v1.1.0.md). Follow Stage 1 through Stage 6
@@ -65,6 +65,10 @@ ckprompt or introduce replacements to conceal this temporary mismatch.
## Stage 1: Migrate the dependency, imports, and removed Go APIs ## Stage 1: Migrate the dependency, imports, and removed Go APIs
**Completed.** Ckconfig now selects ConfigKit v1.1.0 and Go 1.27.0, with
authentic downloaded sums and migrated imports and native API accesses. An
offline compile of its packages and example passed with Go 1.27.0.
1. Inspect the worktree and preserve unrelated work. Select Go 1.27.0 on 1. Inspect the worktree and preserve unrelated work. Select Go 1.27.0 on
`PATH` and confirm it with `GOWORK=off GOTOOLCHAIN=local go version`. `PATH` and confirm it with `GOWORK=off GOTOOLCHAIN=local go version`.
This version was available during planning. Reuse an existing installation, This version was available during planning. Reuse an existing installation,

View File

@@ -10,8 +10,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
type adapterSettings struct { type adapterSettings struct {
@@ -27,7 +27,7 @@ func adapterDefinition() configkit.Definition[adapterSettings] {
validation.Warning(configkit.Keys("greeting"), "using the default greeting") validation.Warning(configkit.Keys("greeting"), "using the default greeting")
} }
}, },
Secret: func(path configkit.Path) bool { return path.String() == "/secret" }, Sensitive: func(path configkit.Path) bool { return path.String() == "/secret" },
} }
} }
@@ -97,7 +97,7 @@ func TestFromConfigKitCompareIgnoresDefaultAndResolutionHistoryForEqualValues(t
Resolve: func(value *resolvedSettings, resolution *configkit.Resolution) error { Resolve: func(value *resolvedSettings, resolution *configkit.Resolution) error {
if value.Greeting != "resolved" { if value.Greeting != "resolved" {
value.Greeting = "resolved" value.Greeting = "resolved"
resolution.Record(configkit.Keys("greeting"), configkit.ChangeNormalization, "canonical greeting") resolution.RecordNormalization(configkit.Keys("greeting"), "canonical greeting")
} }
return nil return nil
}, },

View File

@@ -7,8 +7,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestComparisonCapabilitiesAreIndependentAndCaptured(t *testing.T) { func TestComparisonCapabilitiesAreIndependentAndCaptured(t *testing.T) {

View File

@@ -6,8 +6,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestComparisonSelectionInheritsFieldsIndependently(t *testing.T) { func TestComparisonSelectionInheritsFieldsIndependently(t *testing.T) {

View File

@@ -8,8 +8,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestComparisonPreparesEqualSelectionsWithSeparateTypedInputs(t *testing.T) { func TestComparisonPreparesEqualSelectionsWithSeparateTypedInputs(t *testing.T) {

View File

@@ -7,8 +7,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestCompletionUsesInstalledScopeCapabilitiesWithoutAcquisition(t *testing.T) { func TestCompletionUsesInstalledScopeCapabilitiesWithoutAcquisition(t *testing.T) {

View File

@@ -7,8 +7,8 @@ import (
"io" "io"
"strconv" "strconv"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
// FromConfigKit adapts a typed ConfigKit loader to all five native // FromConfigKit adapts a typed ConfigKit loader to all five native

View File

@@ -4,8 +4,8 @@ import (
"context" "context"
"io" "io"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
// Selection carries the configuration and overlay choices supplied for a // Selection carries the configuration and overlay choices supplied for a

View File

@@ -9,8 +9,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestWithScopeErrorCopiesAndRetainsCauses(t *testing.T) { func TestWithScopeErrorCopiesAndRetainsCauses(t *testing.T) {

View File

@@ -9,8 +9,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )
@@ -273,7 +273,7 @@ func TestConfigDiffExecutesConcealedChangesAndEmptyResults(t *testing.T) {
if selection.Config.Set && selection.Config.Value == "after" { if selection.Config.Set && selection.Config.Value == "after" {
value = "changed-secret" value = "changed-secret"
} }
return configkit.Load(configkit.Mapping("selected", map[string]any{"secret": value}), configkit.Options[settings]{Definition: configkit.Definition[settings]{Secret: func(path configkit.Path) bool { return path.String() == "/secret" }}}) return configkit.Load(configkit.Mapping("selected", map[string]any{"secret": value}), configkit.Options[settings]{Definition: configkit.Definition[settings]{Sensitive: func(path configkit.Path) bool { return path.String() == "/secret" }}})
})) }))
var output bytes.Buffer var output bytes.Buffer
outcome := app.Execute(context.Background(), []string{"config", "diff", "--config", "before", "--against-config", "after"}, commandkit.Streams{Out: &output, Err: io.Discard}) outcome := app.Execute(context.Background(), []string{"config", "diff", "--config", "before", "--against-config", "after"}, commandkit.Streams{Out: &output, Err: io.Discard})

View File

@@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"strings" "strings"
configkit "gitea.maximumdirect.net/eric/ConfigKit" configkit "go.maximumdirect.net/configkit"
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )

View File

@@ -6,7 +6,7 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit" configkit "go.maximumdirect.net/configkit"
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )
@@ -119,7 +119,7 @@ func TestRenderDiffReportPreservesNativeMasksAndMarkerLookingStrings(t *testing.
Public string `yaml:"public"` Public string `yaml:"public"`
Secret string `yaml:"secret"` Secret string `yaml:"secret"`
} }
definition := configkit.Definition[settings]{Secret: func(path configkit.Path) bool { return path.String() == "/secret" }} definition := configkit.Definition[settings]{Sensitive: func(path configkit.Path) bool { return path.String() == "/secret" }}
load := func(public, secret string) *configkit.Result[settings] { load := func(public, secret string) *configkit.Result[settings] {
result, err := configkit.Load(configkit.Mapping("configuration", map[string]any{"public": public, "secret": secret}), configkit.Options[settings]{Definition: definition}) result, err := configkit.Load(configkit.Mapping("configuration", map[string]any{"public": public, "secret": secret}), configkit.Options[settings]{Definition: definition})
if err != nil { if err != nil {

View File

@@ -7,9 +7,9 @@ import (
"os" "os"
"strconv" "strconv"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
"go.maximumdirect.net/ckconfig" "go.maximumdirect.net/ckconfig"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
type appConfiguration struct { type appConfiguration struct {

View File

@@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"io" "io"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
type explanationReport struct { type explanationReport struct {

View File

@@ -9,8 +9,8 @@ import (
"sort" "sort"
"strings" "strings"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
type scopeMetadata struct { type scopeMetadata struct {

View File

@@ -9,8 +9,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
func TestScopeDiscoveryIsOrderedAndDoesNotUseSuiteFactories(t *testing.T) { func TestScopeDiscoveryIsOrderedAndDoesNotUseSuiteFactories(t *testing.T) {

View File

@@ -1,9 +1,10 @@
module go.maximumdirect.net/ckconfig module go.maximumdirect.net/ckconfig
go 1.26.0 go 1.27.0
require ( require (
gitea.maximumdirect.net/eric/ConfigKit v0.8.0 go.maximumdirect.net/commandkit v0.3.0
go.maximumdirect.net/configkit v1.1.0
go.yaml.in/yaml/v4 v4.0.0-rc.6 go.yaml.in/yaml/v4 v4.0.0-rc.6
) )
@@ -11,5 +12,4 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.10.1 // indirect github.com/spf13/cobra v1.10.1 // indirect
github.com/spf13/pflag v1.0.9 // indirect github.com/spf13/pflag v1.0.9 // indirect
go.maximumdirect.net/commandkit v0.3.0
) )

View File

@@ -1,5 +1,3 @@
gitea.maximumdirect.net/eric/ConfigKit v0.8.0 h1:xCIhYnOHjw7rFvB+vIremPKGeROOxKTomnUEUipuQno=
gitea.maximumdirect.net/eric/ConfigKit v0.8.0/go.mod h1:C82sbyKHYMV1OwaD2GJanFrwTfcZfjlW2JsGze5b0kA=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -10,6 +8,8 @@ github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
go.maximumdirect.net/commandkit v0.3.0 h1:RCmg2GS8uzlLSJCIqarpn1uFDec0W3ylNNRRPT6kUFE= go.maximumdirect.net/commandkit v0.3.0 h1:RCmg2GS8uzlLSJCIqarpn1uFDec0W3ylNNRRPT6kUFE=
go.maximumdirect.net/commandkit v0.3.0/go.mod h1:ZS98DewKNVBygKVDoh5MFD09CnPlP37dS9pVsID5Eoc= go.maximumdirect.net/commandkit v0.3.0/go.mod h1:ZS98DewKNVBygKVDoh5MFD09CnPlP37dS9pVsID5Eoc=
go.maximumdirect.net/configkit v1.1.0 h1:UzXN2ZMnEkcL0O4YSLqD9qd9M1gb/NWCHQR/H8AaQzA=
go.maximumdirect.net/configkit v1.1.0/go.mod h1:s1zLJ9GGB/1Q4a+aOHMLISonJxWFgNWpA6SpPlOafeA=
go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4= go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4=
go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"strings" "strings"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
) )
type configCommandInput[I, S any] struct { type configCommandInput[I, S any] struct {

View File

@@ -6,8 +6,8 @@ import (
"io" "io"
"strconv" "strconv"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )
@@ -89,7 +89,7 @@ func runConfigSources[I, S any](invocation commandkit.Invocation, plan *configOp
Path: source.Path, Path: source.Path,
Destination: source.Destination.String(), Destination: source.Destination.String(),
Placement: placement, Placement: placement,
DestinationUnresolved: source.DestinationUnresolved, DestinationUnresolved: source.DestinationIsFallback,
Layer: string(source.Layer), Layer: string(source.Layer),
Kind: string(source.Kind), Kind: string(source.Kind),
UnderlayIndex: source.UnderlayIndex, UnderlayIndex: source.UnderlayIndex,
@@ -97,8 +97,8 @@ func runConfigSources[I, S any](invocation commandkit.Invocation, plan *configOp
if source.ImportedFrom != nil { if source.ImportedFrom != nil {
item.ImportedFrom = &locationDTO{SourceID: source.ImportedFrom.SourceID, Line: source.ImportedFrom.Line, Column: source.ImportedFrom.Column} item.ImportedFrom = &locationDTO{SourceID: source.ImportedFrom.SourceID, Line: source.ImportedFrom.Line, Column: source.ImportedFrom.Column}
} }
if source.VersionCheck != nil { if source.VersionEvidence != nil {
check := source.VersionCheck check := source.VersionEvidence
item.VersionCheck = &sourceVersionCheckDTO{ item.VersionCheck = &sourceVersionCheckDTO{
Path: check.Path.String(), Path: check.Path.String(),
Version: versionDTO{ Version: versionDTO{

View File

@@ -8,8 +8,8 @@ import (
"strings" "strings"
"testing" "testing"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
commandkit "go.maximumdirect.net/commandkit" commandkit "go.maximumdirect.net/commandkit"
configkit "go.maximumdirect.net/configkit"
"go.yaml.in/yaml/v4" "go.yaml.in/yaml/v4"
) )
@@ -39,8 +39,8 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
{ {
ID: "item", Label: "sequence item", Path: "item.yml", ID: "item", Label: "sequence item", Path: "item.yml",
Destination: servicePath, PlacementMode: configkit.PlacementModeSequenceItem, Destination: servicePath, PlacementMode: configkit.PlacementModeSequenceItem,
DestinationUnresolved: true, DestinationIsFallback: true,
VersionCheck: &configkit.SourceVersionCheck{ VersionEvidence: &configkit.SourceVersionEvidence{
Path: versionPath, Path: versionPath,
Version: configkit.Version{Present: true, Text: "v2"}, Version: configkit.Version{Present: true, Text: "v2"},
Location: &configkit.Location{SourceID: "item.yml", Line: 4, Column: 2}, Location: &configkit.Location{SourceID: "item.yml", Line: 4, Column: 2},
@@ -49,7 +49,7 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
{ {
ID: "null", Label: "null version", Path: "null.yml", ID: "null", Label: "null version", Path: "null.yml",
Destination: otherPath, PlacementMode: configkit.PlacementModeMapping, Destination: otherPath, PlacementMode: configkit.PlacementModeMapping,
VersionCheck: &configkit.SourceVersionCheck{ VersionEvidence: &configkit.SourceVersionEvidence{
Path: nullVersionPath, Path: nullVersionPath,
Version: configkit.Version{Present: true, Null: true}, Version: configkit.Version{Present: true, Null: true},
Redacted: true, Redacted: true,