Align reporting contracts and documentation
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:") {
|
||||
|
||||
Reference in New Issue
Block a user