Unify effective config projection
This commit is contained in:
107
internal/config/effective_projection.go
Normal file
107
internal/config/effective_projection.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// effectivePipelineProjection is the single safe, schema-specific view used
|
||||
// for inspection, comparison, and identity. Runtime metadata and unresolved
|
||||
// family declarations have no slot in this type.
|
||||
type effectivePipelineProjection struct {
|
||||
Workspace WorkspaceConfig `yaml:"workspace" json:"workspace"`
|
||||
Campaigns CampaignsConfig `yaml:"campaigns" json:"campaigns"`
|
||||
Storage StorageConfig `yaml:"storage" json:"storage"`
|
||||
Spool SpoolConfig `yaml:"spool" json:"spool"`
|
||||
Cache CacheConfig `yaml:"cache" json:"cache"`
|
||||
Publish *PublishConfig `yaml:"publish" json:"publish"`
|
||||
Secrets *SecretsConfig `yaml:"secrets" json:"secrets"`
|
||||
WhisperX WhisperXConfig `yaml:"whisperx" json:"whisperx"`
|
||||
Seriatim SeriatimConfig `yaml:"seriatim" json:"seriatim"`
|
||||
Audita AuditaConfig `yaml:"audita" json:"audita"`
|
||||
Normalize *NormalizeConfig `yaml:"normalize" json:"normalize"`
|
||||
Trim *TrimConfig `yaml:"trim" json:"trim"`
|
||||
Render *RenderConfig `yaml:"render" json:"render"`
|
||||
Scriptorium *effectiveScriptoriumConfig `yaml:"scriptorium" json:"scriptorium"`
|
||||
Notarius *NotariusConfig `yaml:"notarius" json:"notarius"`
|
||||
Notification NotificationConfig `yaml:"notification" json:"notification"`
|
||||
}
|
||||
|
||||
type effectiveScriptoriumConfig struct {
|
||||
Binary string `yaml:"binary" json:"binary"`
|
||||
ConfigPath string `yaml:"config_path" json:"config_path"`
|
||||
Timeout string `yaml:"timeout" json:"timeout"`
|
||||
RenderDebug bool `yaml:"render_debug" json:"render_debug"`
|
||||
Artifacts map[string]ScriptoriumArtifactConfig `yaml:"artifacts" json:"artifacts"`
|
||||
}
|
||||
|
||||
func projectEffectivePipeline(cfg *PipelineConfig, logicalNotarius bool) effectivePipelineProjection {
|
||||
projection := effectivePipelineProjection{
|
||||
Workspace: cfg.Workspace, Campaigns: cfg.Campaigns, Storage: cfg.Storage,
|
||||
Spool: cfg.Spool, Cache: cfg.Cache, Publish: cfg.Publish, Secrets: cfg.Secrets,
|
||||
WhisperX: cfg.WhisperX, Seriatim: cfg.Seriatim, Audita: cfg.Audita,
|
||||
Normalize: cfg.Normalize, Trim: cfg.Trim, Render: cfg.Render,
|
||||
Notarius: cfg.Notarius, Notification: cfg.Notification,
|
||||
}
|
||||
if cfg.Scriptorium != nil {
|
||||
projection.Scriptorium = &effectiveScriptoriumConfig{
|
||||
Binary: cfg.Scriptorium.Binary, ConfigPath: cfg.Scriptorium.ConfigPath,
|
||||
Timeout: cfg.Scriptorium.Timeout, RenderDebug: cfg.Scriptorium.RenderDebug,
|
||||
Artifacts: cfg.Scriptorium.Artifacts,
|
||||
}
|
||||
}
|
||||
if logicalNotarius && cfg.Notarius != nil && cfg.resolution != nil && cfg.resolution.logicalNotariusCaptured {
|
||||
notarius := *cfg.Notarius
|
||||
notarius.ConfigPath = cfg.resolution.logicalNotariusConfig
|
||||
notarius.WorkingDirectory = cfg.resolution.logicalNotariusWorking
|
||||
projection.Notarius = ¬arius
|
||||
}
|
||||
return projection
|
||||
}
|
||||
|
||||
func projectionJSON(projection effectivePipelineProjection) ([]byte, error) {
|
||||
data, err := json.Marshal(projection)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode effective pipeline projection: %w", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func projectionValueRecords(projection effectivePipelineProjection) ([]EffectivePipelineValueRecord, error) {
|
||||
data, err := projectionJSON(projection)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.UseNumber()
|
||||
var root map[string]any
|
||||
if err := decoder.Decode(&root); err != nil {
|
||||
return nil, fmt.Errorf("decode effective pipeline projection: %w", err)
|
||||
}
|
||||
var records []EffectivePipelineValueRecord
|
||||
appendProjectionRecords(&records, "", root)
|
||||
sort.Slice(records, func(i, j int) bool { return records[i].Path < records[j].Path })
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func appendProjectionRecords(records *[]EffectivePipelineValueRecord, path string, value any) {
|
||||
if mapping, ok := value.(map[string]any); ok && len(mapping) > 0 {
|
||||
keys := make([]string, 0, len(mapping))
|
||||
for key := range mapping {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, key := range keys {
|
||||
childPath := key
|
||||
if path != "" {
|
||||
childPath = path + "." + key
|
||||
}
|
||||
appendProjectionRecords(records, childPath, mapping[key])
|
||||
}
|
||||
return
|
||||
}
|
||||
encoded, _ := json.Marshal(value)
|
||||
*records = append(*records, EffectivePipelineValueRecord{Path: path, Value: string(encoded)})
|
||||
}
|
||||
Reference in New Issue
Block a user