Preserve null collections in effective YAML

This commit is contained in:
2026-09-07 12:03:45 +00:00
parent 47b3e5b55b
commit 3ec54b8c72
5 changed files with 170 additions and 12 deletions

View File

@@ -1,9 +1,11 @@
package config
import (
"encoding/json"
"fmt"
"path/filepath"
"sort"
"strconv"
"strings"
"gopkg.in/yaml.v3"
@@ -151,13 +153,72 @@ func MarshalEffectivePipeline(cfg *PipelineConfig) ([]byte, error) {
return nil, fmt.Errorf("pipeline config is required")
}
data, err := yaml.Marshal(projectEffectivePipeline(cfg, true))
value, err := projectionValueTree(projectEffectivePipeline(cfg, true))
if err != nil {
return nil, err
}
node, err := effectiveYAMLNode(value)
if err != nil {
return nil, fmt.Errorf("serialize effective pipeline: %w", err)
}
data, err := yaml.Marshal(node)
if err != nil {
return nil, fmt.Errorf("serialize effective pipeline: %w", err)
}
return data, nil
}
func effectiveYAMLNode(value any) (*yaml.Node, error) {
switch value := value.(type) {
case nil:
return &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!null", Value: "null"}, nil
case bool:
return &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!bool", Value: strconv.FormatBool(value)}, nil
case string:
return &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: value}, nil
case json.Number:
tag := "!!int"
if strings.ContainsAny(value.String(), ".eE") {
tag = "!!float"
}
return &yaml.Node{Kind: yaml.ScalarNode, Tag: tag, Value: value.String()}, nil
case []any:
node := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
if len(value) == 0 {
node.Style = yaml.FlowStyle
}
for _, item := range value {
child, err := effectiveYAMLNode(item)
if err != nil {
return nil, err
}
node.Content = append(node.Content, child)
}
return node, nil
case map[string]any:
node := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
if len(value) == 0 {
node.Style = yaml.FlowStyle
}
keys := make([]string, 0, len(value))
for key := range value {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
child, err := effectiveYAMLNode(value[key])
if err != nil {
return nil, err
}
node.Content = append(node.Content,
&yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: key}, child)
}
return node, nil
default:
return nil, fmt.Errorf("unsupported projected value type %T", value)
}
}
func effectivePipelineOwners(cfg *PipelineConfig) map[string][]string {
owners := make(map[string][]string)
if cfg == nil || cfg.resolution == nil {