81 lines
2.5 KiB
Go
81 lines
2.5 KiB
Go
package llm
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/audita/v3/internal/core/config"
|
|
ck "go.maximumdirect.net/configkit"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
type derivationView struct {
|
|
Operation ck.ChangeKind `yaml:"operation"`
|
|
Reason string `yaml:"reason"`
|
|
Dependencies []string `yaml:"dependencies,omitempty"`
|
|
}
|
|
type inheritanceStepView struct {
|
|
From string `yaml:"from"`
|
|
To string `yaml:"to"`
|
|
Reference string `yaml:"reference"`
|
|
}
|
|
type explanationView struct {
|
|
Path string `yaml:"path"`
|
|
Source string `yaml:"source"`
|
|
Layer ck.Layer `yaml:"layer"`
|
|
Derivations []derivationView `yaml:"derivations,omitempty"`
|
|
Inheritance []inheritanceStepView `yaml:"inheritance,omitempty"`
|
|
}
|
|
|
|
// ExplanationYAML reports only origins and recorded resolution operations.
|
|
// It intentionally excludes effective and historical values, including secrets.
|
|
func ExplanationYAML(result *ck.Result[config.Config]) ([]byte, error) {
|
|
if result == nil {
|
|
return nil, fmt.Errorf("configuration result is unavailable")
|
|
}
|
|
metadata := result.Metadata()
|
|
sources := make(map[string]string)
|
|
for _, source := range result.Sources() {
|
|
sources[source.ID] = source.Label
|
|
}
|
|
records := make([]explanationView, 0)
|
|
paths := metadata.HistoricalPaths()
|
|
for i, path := range paths {
|
|
if path.String() == "" {
|
|
continue
|
|
}
|
|
if i+1 < len(paths) && strings.HasPrefix(paths[i+1].String(), path.String()+"/") {
|
|
continue
|
|
}
|
|
info, ok := metadata.Lookup(path)
|
|
if !ok {
|
|
continue
|
|
}
|
|
record := explanationView{Path: path.String(), Layer: info.Origin.Layer, Source: string(info.Origin.Layer)}
|
|
for _, step := range info.Origin.Inheritance {
|
|
record.Inheritance = append(record.Inheritance, inheritanceStepView{
|
|
From: step.From.String(), To: step.To.String(), Reference: step.Reference.String(),
|
|
})
|
|
}
|
|
if len(info.Origin.Locations) > 0 {
|
|
if label := sources[info.Origin.Locations[0].SourceID]; label != "" {
|
|
record.Source = label
|
|
}
|
|
}
|
|
for _, change := range metadata.History(path) {
|
|
if change.Origin.Layer != ck.LayerResolution {
|
|
continue
|
|
}
|
|
for _, reason := range change.Reasons {
|
|
derivation := derivationView{Operation: change.Origin.Operation, Reason: reason}
|
|
for _, dependency := range change.Dependencies {
|
|
derivation.Dependencies = append(derivation.Dependencies, dependency.String())
|
|
}
|
|
record.Derivations = append(record.Derivations, derivation)
|
|
}
|
|
}
|
|
records = append(records, record)
|
|
}
|
|
return yaml.Marshal(records)
|
|
}
|