Align reporting contracts and documentation

This commit is contained in:
2026-11-07 05:06:47 +00:00
parent 1289868ed0
commit d14fa366f5
17 changed files with 160 additions and 169 deletions

View File

@@ -28,7 +28,7 @@ ConfigKit loader. The `config` command family exposes scope discovery and the
validate, show, sources, explain, and diff operations supported by the declared
scopes. Source reports include native destination, placement, destination
fallback, version evidence, and empty-import selections. Comparison returns
ConfigKit's native records to the YAML report path; the
ConfigKit's native records to shared report rendering; the
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections)
owns its operator details.

View File

@@ -47,7 +47,7 @@ type Request struct {
// 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 carries the explicit config, overlay, and override inputs for this side.
Selection Selection
// Input is initialized and checked for this side before comparison.
Input I
@@ -118,7 +118,7 @@ type ScopeFeatures struct {
type Scope[I, S any] struct {
// Name identifies the scope in CLI selection and reports.
Name string
// Summary describes the scope. Scope discovery reports name and operations only.
// Summary describes the scope.
Summary string
// Operations selects the standard handlers exposed for this scope.
Operations []Operation

View File

@@ -11,12 +11,12 @@ import (
)
type explanationReport struct {
Scope string `json:"scope" yaml:"scope"`
Path string `json:"path" yaml:"path"`
Effective snapshotDTO `json:"effective" yaml:"effective"`
Origin explanationOriginDTO `json:"origin" yaml:"origin"`
History []explanationChangeDTO `json:"history" yaml:"history"`
SecretReference *secretReferenceDTO `json:"secret_reference" yaml:"secret_reference"`
Scope string `json:"scope"`
Path string `json:"path"`
Effective snapshotDTO `json:"effective"`
Origin explanationOriginDTO `json:"origin"`
History []explanationChangeDTO `json:"history"`
SecretReference *secretReferenceDTO `json:"secret_reference"`
Metadata *explanationMetadata `json:"metadata,omitempty"`
}
@@ -49,35 +49,35 @@ type pathMetadata struct {
var pathDiscoveryTemplate = template.Must(commandkit.ParseTextTemplate("paths", "{{range .Paths}}{{printf \"%q\" .Path}} {{if .Present}}{{if .Metadata.Explicit}}explicit{{else}}non-explicit{{end}}{{else}}historical{{end}}\n{{end}}", nil))
type snapshotDTO struct {
Present bool `json:"present" yaml:"present"`
Redacted bool `json:"redacted" yaml:"redacted"`
YAML string `json:"yaml" yaml:"yaml"`
Present bool `json:"present"`
Redacted bool `json:"redacted"`
YAML string `json:"yaml"`
}
type explanationOriginDTO struct {
Layer string `json:"layer" yaml:"layer"`
Locations []locationDTO `json:"locations" yaml:"locations"`
Operation string `json:"operation" yaml:"operation"`
Inheritance []inheritanceStepDTO `json:"inheritance" yaml:"inheritance"`
Layer string `json:"layer"`
Locations []locationDTO `json:"locations"`
Operation string `json:"operation"`
Inheritance []inheritanceStepDTO `json:"inheritance"`
}
type inheritanceStepDTO struct {
From string `json:"from" yaml:"from"`
To string `json:"to" yaml:"to"`
Reference string `json:"reference" yaml:"reference"`
Locations []locationDTO `json:"locations" yaml:"locations"`
From string `json:"from"`
To string `json:"to"`
Reference string `json:"reference"`
Locations []locationDTO `json:"locations"`
}
type explanationChangeDTO struct {
Before snapshotDTO `json:"before" yaml:"before"`
After snapshotDTO `json:"after" yaml:"after"`
Origin explanationOriginDTO `json:"origin" yaml:"origin"`
Reasons []string `json:"reasons" yaml:"reasons"`
Dependencies []string `json:"dependencies" yaml:"dependencies"`
Before snapshotDTO `json:"before"`
After snapshotDTO `json:"after"`
Origin explanationOriginDTO `json:"origin"`
Reasons []string `json:"reasons"`
Dependencies []string `json:"dependencies"`
}
type secretReferenceDTO struct {
Name string `json:"name" yaml:"name"`
Name string `json:"name"`
}
func runConfigExplanation[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome {

View File

@@ -10,48 +10,48 @@ import (
)
type sourceReport struct {
Scope string `json:"scope" yaml:"scope"`
Sources []sourceDTO `json:"sources" yaml:"sources"`
Scope string `json:"scope"`
Sources []sourceDTO `json:"sources"`
}
type sourceDTO struct {
ID string `json:"id" yaml:"id"`
Label string `json:"label" yaml:"label"`
Path string `json:"path" yaml:"path"`
Destination string `json:"destination" yaml:"destination"`
Placement string `json:"placement" yaml:"placement"`
DestinationIsFallback bool `json:"destination_is_fallback" yaml:"destination_is_fallback"`
Layer string `json:"layer" yaml:"layer"`
Kind string `json:"kind" yaml:"kind"`
UnderlayIndex int `json:"underlay_index" yaml:"underlay_index"`
ImportedFrom *locationDTO `json:"imported_from" yaml:"imported_from"`
VersionEvidence *sourceVersionEvidenceDTO `json:"version_evidence" yaml:"version_evidence"`
EmptyImportSelections []emptyImportSelectionDTO `json:"empty_import_selections" yaml:"empty_import_selections"`
ID string `json:"id"`
Label string `json:"label"`
Path string `json:"path"`
Destination string `json:"destination"`
Placement string `json:"placement"`
DestinationIsFallback bool `json:"destination_is_fallback"`
Layer string `json:"layer"`
Kind string `json:"kind"`
UnderlayIndex int `json:"underlay_index"`
ImportedFrom *locationDTO `json:"imported_from"`
VersionEvidence *sourceVersionEvidenceDTO `json:"version_evidence"`
EmptyImportSelections []emptyImportSelectionDTO `json:"empty_import_selections"`
}
type emptyImportSelectionDTO struct {
Path string `json:"path" yaml:"path"`
Location locationDTO `json:"location" yaml:"location"`
Selector string `json:"selector" yaml:"selector"`
Path string `json:"path"`
Location locationDTO `json:"location"`
Selector string `json:"selector"`
}
type locationDTO struct {
SourceID string `json:"source_id" yaml:"source_id"`
Line int `json:"line" yaml:"line"`
Column int `json:"column" yaml:"column"`
SourceID string `json:"source_id"`
Line int `json:"line"`
Column int `json:"column"`
}
type sourceVersionEvidenceDTO struct {
Path string `json:"path" yaml:"path"`
Version versionDTO `json:"version" yaml:"version"`
Location *locationDTO `json:"location" yaml:"location"`
Redacted bool `json:"redacted" yaml:"redacted"`
Path string `json:"path"`
Version versionDTO `json:"version"`
Location *locationDTO `json:"location"`
Redacted bool `json:"redacted"`
}
type versionDTO struct {
Present bool `json:"present" yaml:"present"`
Null bool `json:"null" yaml:"null"`
Text string `json:"text" yaml:"text"`
Present bool `json:"present"`
Null bool `json:"null"`
Text string `json:"text"`
}
func runConfigSources[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome {

View File

@@ -74,12 +74,20 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
var report struct {
Scope string `yaml:"scope"`
Sources []struct {
ID string `yaml:"id"`
Destination string `yaml:"destination"`
Placement string `yaml:"placement"`
Layer string `yaml:"layer"`
EmptyImportSelections []emptyImportSelectionDTO `yaml:"empty_import_selections"`
DestinationIsFallback bool `yaml:"destination_is_fallback"`
ID string `yaml:"id"`
Destination string `yaml:"destination"`
Placement string `yaml:"placement"`
Layer string `yaml:"layer"`
EmptyImportSelections []struct {
Path string `yaml:"path"`
Location struct {
SourceID string `yaml:"source_id"`
Line int `yaml:"line"`
Column int `yaml:"column"`
} `yaml:"location"`
Selector string `yaml:"selector"`
} `yaml:"empty_import_selections"`
DestinationIsFallback bool `yaml:"destination_is_fallback"`
VersionEvidence *struct {
Path string `yaml:"path"`
Version struct {
@@ -108,11 +116,8 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) {
if root := report.Sources[0]; root.Destination != "" || root.Placement != "mapping" || root.DestinationIsFallback || root.VersionEvidence != nil || root.Layer != "main" {
t.Errorf("root source projection = %#v", root)
}
wantSelections := []emptyImportSelectionDTO{
{Path: "/imports/first", Location: locationDTO{SourceID: "root.yml", Line: 3, Column: 4}, Selector: "glob"},
{Path: "/imports/second", Location: locationDTO{}, Selector: "path"},
}
if !reflect.DeepEqual(report.Sources[0].EmptyImportSelections, wantSelections) || report.Sources[1].EmptyImportSelections == nil || len(report.Sources[1].EmptyImportSelections) != 0 {
selections := report.Sources[0].EmptyImportSelections
if len(selections) != 2 || selections[0].Path != "/imports/first" || selections[0].Location.SourceID != "root.yml" || selections[0].Location.Line != 3 || selections[0].Location.Column != 4 || selections[0].Selector != "glob" || selections[1].Path != "/imports/second" || selections[1].Selector != "path" || report.Sources[1].EmptyImportSelections == nil || len(report.Sources[1].EmptyImportSelections) != 0 {
t.Fatalf("import selections: %#v", report.Sources)
}
if strings.Contains(yamlOutput.String(), "destination_unresolved:") || strings.Contains(yamlOutput.String(), "version_check:") {