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.SubstituteNode(newMap, val) } return toMap }
func ProcessKeyTag(val yaml.Node) (yaml.Node, string) { keyName := "" m, ok := val.Value().(map[string]yaml.Node) if ok { found := false for key, _ := range m { split := strings.Index(key, ":") if split > 0 { if key[:split] == "key" { keyName = key[split+1:] found = true } } } if found { newMap := make(map[string]yaml.Node) for key, v := range m { split := strings.Index(key, ":") if split > 0 { if key[:split] == "key" { key = key[split+1:] } } newMap[key] = v } return yaml.SubstituteNode(newMap, val), keyName } } return val, keyName }
func flowList(root yaml.Node, env Environment) yaml.Node { rootList := root.Value().([]yaml.Node) debug.Debug("HANDLE LIST %v\n", env.Path) merged, process, replaced, redirectPath, keyName := processMerges(root, rootList, env) if process { newList := []yaml.Node{} if len(redirectPath) > 0 { env = env.RedirectOverwrite(redirectPath) } for idx, val := range merged { step := stepName(idx, val, keyName) debug.Debug(" step %s\n", step) newList = append(newList, flow(val, env.WithPath(step), false)) } merged = newList } if keyName != "" { root = yaml.KeyNameNode(root, keyName) } debug.Debug("LIST DONE (%s)%v\n", root.KeyName(), env.Path) if replaced { return yaml.ReplaceNode(merged, root, redirectPath) } if len(redirectPath) > 0 { return yaml.RedirectNode(merged, root, redirectPath) } return yaml.SubstituteNode(merged, root) }
func processMerges(orig yaml.Node, root []yaml.Node, env Environment) ([]yaml.Node, bool, bool, []string, string) { spliced := []yaml.Node{} process := true keyName := orig.KeyName() replaced := orig.ReplaceFlag() redirectPath := orig.RedirectPath() for _, val := range root { if val == nil { continue } inlineNode, ok := yaml.UnresolvedListEntryMerge(val) if ok { debug.Debug("*** %+v\n", inlineNode.Value()) _, initial := inlineNode.Value().(string) result := flow(inlineNode, env, false) if result.KeyName() != "" { keyName = result.KeyName() } debug.Debug("=== (%s)%+v\n", keyName, result) _, ok := result.Value().(dynaml.Expression) if ok { if simpleMergeCompatibilityCheck(initial, inlineNode) { continue } newMap := make(map[string]yaml.Node) newMap["<<"] = result val = yaml.SubstituteNode(newMap, orig) process = false } else { inline, ok := result.Value().([]yaml.Node) if ok { inlineNew := newEntries(inline, root, keyName) replaced = result.ReplaceFlag() redirectPath = result.RedirectPath() if replaced { spliced = inlineNew process = false break } else { spliced = append(spliced, inlineNew...) } } continue } } val, newKey := ProcessKeyTag(val) if newKey != "" { keyName = newKey } spliced = append(spliced, val) } debug.Debug("--> %+v proc=%v replaced=%v redirect=%v key=%s\n", spliced, process, replaced, redirectPath, keyName) return spliced, process, replaced, redirectPath, keyName }
func flowString(root yaml.Node, env Environment) yaml.Node { sub := yaml.EmbeddedDynaml(root) if sub == nil { return root } debug.Debug("dynaml: %v: %s\n", env.Path, *sub) expr, err := dynaml.Parse(*sub, env.Path, env.StubPath) if err != nil { return root } return yaml.SubstituteNode(expr, root) }