func flowMap(root yaml.Node, env Environment) yaml.Node { rootMap := root.Value().(map[string]yaml.Node) env = env.WithScope(rootMap) newMap := make(map[string]yaml.Node) sortedKeys := getSortedKeys(rootMap) // iteration order matters for the "<<" operator, it must be the first key in the map that is handled for i := range sortedKeys { key := sortedKeys[i] val := rootMap[key] if key == "<<" { base := flow(val, env, true) baseMap, ok := base.Value().(map[string]yaml.Node) if ok { for k, v := range baseMap { newMap[k] = v } } continue } newMap[key] = flow(val, env.WithPath(key), true) } return yaml.NewNode(newMap, root.SourceName()) }
func flowMap(root yaml.Node, env Environment) yaml.Node { rootMap := root.Value().(map[string]yaml.Node) env = env.WithScope(rootMap) newMap := make(map[string]yaml.Node) for key, val := range rootMap { if key == "<<" { base := flow(val, env, true) baseMap, ok := base.Value().(map[string]yaml.Node) if ok { for k, v := range baseMap { newMap[k] = v } } continue } newMap[key] = flow(val, env.WithPath(key), true) } return yaml.NewNode(newMap, root.SourceName()) }
func (e Environment) FindFromRoot(path []string) (yaml.Node, bool) { if len(e.Scope) == 0 { return nil, false } return yaml.FindR(true, yaml.NewNode(e.Scope[0], "scope"), path...) }
func listToMap(list []yaml.Node) map[string]yaml.Node { toMap := make(map[string]yaml.Node) for _, val := range list { name, ok := yaml.FindString(val, "name") if !ok { return nil } asMap, ok := val.Value().(map[string]yaml.Node) if !ok { return nil } newMap := make(map[string]yaml.Node) for key, val := range asMap { if key != "name" { newMap[key] = val } } toMap[name] = yaml.NewNode(newMap, val.SourceName()) } return toMap }
func jobMap(jobs []yaml.Node) map[string]yaml.Node { byName := make(map[string]yaml.Node) for index, job := range jobs { attrs, ok := job.Value().(map[string]yaml.Node) attrs["index"] = yaml.NewNode(index, job.SourceName()) name, ok := yaml.FindString(job, "name") if !ok { panic("job without string name") } byName[name] = yaml.NewNode(attrs, job.SourceName()) } return byName }
func flowList(root yaml.Node, env Environment) yaml.Node { rootList := root.Value().([]yaml.Node) merged := processMerges(rootList, env) newList := []yaml.Node{} for idx, val := range merged { step := stepName(idx, val) newList = append(newList, flow(val, env.WithPath(step), false)) } return yaml.NewNode(newList, root.SourceName()) }
func flowString(root yaml.Node, env Environment) yaml.Node { rootString := root.Value().(string) sub := embeddedDynaml.FindStringSubmatch(rootString) if sub == nil { return root } expr, err := dynaml.Parse(sub[1], env.Path) if err != nil { return root } return yaml.NewNode(expr, root.SourceName()) }
func newEntries(a []yaml.Node, b []yaml.Node) []yaml.Node { added := []yaml.Node{} for _, val := range a { name, ok := yaml.FindString(val, "name") if ok { _, found := yaml.Find(yaml.NewNode(b, "some map"), name) // TODO if found { continue } } added = append(added, val) } return added }
func newEntries(a []yaml.Node, b []yaml.Node, keyName string) []yaml.Node { if keyName == "" { keyName = "name" } old := yaml.KeyNameNode(yaml.NewNode(b, "some map"), keyName) added := []yaml.Node{} for _, val := range a { name, ok := yaml.FindStringR(true, val, keyName) if ok { _, found := yaml.FindR(true, old, name) // TODO if found { continue } } added = append(added, val) } return added }
}) }) Context("when some dynaml nodes cannot be resolved", func() { It("returns an error", func() { source := parseYAML(` --- foo: (( auto )) `) _, err := Flow(source) Expect(err).To(Equal(UnresolvedNodes{ Nodes: []UnresolvedNode{ { Node: yaml.NewNode( dynaml.AutoExpr{Path: []string{"foo"}}, "test", ), Context: []string{"foo"}, Path: []string{"foo"}, }, }, })) }) }) Context("when a reference is made to a yet-to-be-resolved node, in a || expression", func() { It("eventually resolves to the referenced node", func() { source := parseYAML(` --- properties: template_only: (( merge ))
import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/cloudfoundry-incubator/spiff/dynaml" "github.com/cloudfoundry-incubator/spiff/yaml" ) var _ = Describe("Reporting unresolved nodes", func() { It("formats a message listing the nodes", func() { err := UnresolvedNodes{ Nodes: []UnresolvedNode{ { Node: yaml.NewNode( dynaml.AutoExpr{}, "some-file.yml", ), Context: []string{"foo", "bar"}, Path: []string{"foo", "bar"}, }, { Node: yaml.NewNode( dynaml.MergeExpr{}, "some-other-file.yml", ), Context: []string{"fizz", "[2]", "buzz"}, Path: []string{"fizz", "fizzbuzz", "buzz"}, }, }, }
}) }) Context("when some dynaml nodes cannot be resolved", func() { It("returns an error", func() { source := parseYAML(` --- foo: (( auto )) `) _, err := Flow(source) Expect(err).To(Equal(dynaml.UnresolvedNodes{ Nodes: []dynaml.UnresolvedNode{ { Node: yaml.IssueNode(yaml.NewNode( dynaml.AutoExpr{Path: []string{"foo"}}, "test", ), "auto only allowed for size entry in resource pools"), Context: []string{"foo"}, Path: []string{"foo"}, }, }, })) }) }) Context("when a reference is made to a yet-to-be-resolved node, in a || expression", func() { It("eventually resolves to the referenced node", func() { source := parseYAML(` --- properties: template_only: (( merge ))
func node(val interface{}) yaml.Node { return yaml.NewNode(val, "dynaml") }