Added more support for YAML merge nodes, anchors and aliases

And added deeper support for Aliases. Also added in local file handling through renamed `FSHandler` configuration property for the index.

Also re-ran `go fmt`

Signed-off-by: Dave Shanley <dave@quobix.com>
This commit is contained in:
Dave Shanley
2023-07-15 10:18:49 -04:00
committed by quobix
parent 3b7cbacc44
commit 25d8de9b0e
48 changed files with 925 additions and 531 deletions

View File

@@ -196,9 +196,9 @@ func FindFirstKeyNode(key string, nodes []*yaml.Node, depth int) (keyNode *yaml.
for i, v := range nodes {
if key != "" && key == v.Value {
if i+1 >= len(nodes) {
return v, nodes[i] // this is the node we need.
return v, NodeAlias(nodes[i]) // this is the node we need.
}
return v, nodes[i+1] // next node is what we need.
return v, NodeAlias(nodes[i+1]) // next node is what we need.
}
if len(v.Content) > 0 {
depth++
@@ -283,12 +283,12 @@ func FindKeyNodeFull(key string, nodes []*yaml.Node) (keyNode *yaml.Node, labelN
if key == v.Content[x].Value {
if IsNodeMap(v) {
if x+1 == len(v.Content) {
return v, v.Content[x], v.Content[x]
return v, v.Content[x], NodeAlias(v.Content[x])
}
return v, v.Content[x], v.Content[x+1]
return v, v.Content[x], NodeAlias(v.Content[x+1])
}
if IsNodeArray(v) {
return v, v.Content[x], v.Content[x]
return v, v.Content[x], NodeAlias(v.Content[x])
}
}
}
@@ -304,7 +304,7 @@ func FindKeyNodeFullTop(key string, nodes []*yaml.Node) (keyNode *yaml.Node, lab
continue
}
if i%2 == 0 && key == nodes[i].Value {
return nodes[i], nodes[i], nodes[i+1] // next node is what we need.
return nodes[i], nodes[i], NodeAlias(nodes[i+1]) // next node is what we need.
}
}
return nil, nil, nil
@@ -322,7 +322,7 @@ func FindExtensionNodes(nodes []*yaml.Node) []*ExtensionNode {
if i+1 < len(nodes) {
extensions = append(extensions, &ExtensionNode{
Key: v,
Value: nodes[i+1],
Value: NodeAlias(nodes[i+1]),
})
}
}
@@ -363,12 +363,38 @@ func IsNodeMap(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!map"
n := NodeAlias(node)
return n.Tag == "!!map"
}
// IsNodeAlias checks if the node is an alias, and lifts out the anchor
func IsNodeAlias(node *yaml.Node) (*yaml.Node, bool) {
if node == nil {
return nil, false
}
if node.Kind == yaml.AliasNode {
node = node.Alias
return node, true
}
return node, false
}
// NodeAlias checks if the node is an alias, and lifts out the anchor
func NodeAlias(node *yaml.Node) *yaml.Node {
if node == nil {
return nil
}
if node.Kind == yaml.AliasNode {
node = node.Alias
return node
}
return node
}
// IsNodePolyMorphic will return true if the node contains polymorphic keys.
func IsNodePolyMorphic(node *yaml.Node) bool {
for i, v := range node.Content {
n := NodeAlias(node)
for i, v := range n.Content {
if i%2 == 0 {
if v.Value == "anyOf" || v.Value == "oneOf" || v.Value == "allOf" {
return true
@@ -383,7 +409,8 @@ func IsNodeArray(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!seq"
n := NodeAlias(node)
return n.Tag == "!!seq"
}
// IsNodeStringValue checks if a node is a string value
@@ -391,7 +418,8 @@ func IsNodeStringValue(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!str"
n := NodeAlias(node)
return n.Tag == "!!str"
}
// IsNodeIntValue will check if a node is an int value
@@ -399,7 +427,8 @@ func IsNodeIntValue(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!int"
n := NodeAlias(node)
return n.Tag == "!!int"
}
// IsNodeFloatValue will check is a node is a float value.
@@ -407,7 +436,8 @@ func IsNodeFloatValue(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!float"
n := NodeAlias(node)
return n.Tag == "!!float"
}
// IsNodeNumberValue will check if a node can be parsed as a float value.
@@ -423,18 +453,20 @@ func IsNodeBoolValue(node *yaml.Node) bool {
if node == nil {
return false
}
return node.Tag == "!!bool"
n := NodeAlias(node)
return n.Tag == "!!bool"
}
func IsNodeRefValue(node *yaml.Node) (bool, *yaml.Node, string) {
if node == nil {
return false, nil, ""
}
for i, r := range node.Content {
n := NodeAlias(node)
for i, r := range n.Content {
if i%2 == 0 {
if r.Value == "$ref" {
return true, r, node.Content[i+1].Value
return true, r, n.Content[i+1].Value
}
}
}
@@ -691,3 +723,26 @@ func DetermineWhitespaceLength(input string) int {
return 0
}
}
// CheckForMergeNodes will check the top level of the schema for merge nodes. If any are found, then the merged nodes
// will be appended to the end of the rest of the nodes in the schema.
// Note: this is a destructive operation, so the in-memory node structure will be modified
func CheckForMergeNodes(node *yaml.Node) {
if node == nil {
return
}
total := len(node.Content)
for i := 0; i < total; i++ {
mn := node.Content[i]
if i%2 == 0 {
if mn.Tag == "!!merge" {
an := node.Content[i+1].Alias
if an != nil {
node.Content = append(node.Content, an.Content...) // append the merged nodes
total = len(node.Content)
i += 2
}
}
}
}
}