-
Notifications
You must be signed in to change notification settings - Fork 239
/
sourceinfo.go
52 lines (46 loc) · 1.41 KB
/
sourceinfo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package sourceinfo
import (
"fmt"
"io/ioutil"
"strconv"
"gopkg.in/yaml.v3"
)
// findNode recursively iterates through the yaml file using the node feature. The function
// will continue until the token is found at the max depth. If the token is not found, an
// empty node is returned.
func findNode(node *yaml.Node, keyIndex int, maxDepth int, keys []string) (*yaml.Node, error) {
for i := 0; i < len(node.Content); i += 2 {
key := node.Content[i]
val := node.Content[i+1]
if keyIndex+1 == maxDepth && val.Value == keys[maxDepth] {
return val, nil
}
if key.Value == keys[keyIndex] {
switch val.Kind {
case yaml.SequenceNode:
nextKeyIndex, err := strconv.Atoi(keys[keyIndex+1])
if err != nil {
return nil, err
}
return findNode(val.Content[nextKeyIndex], keyIndex+2, maxDepth, keys)
default:
return findNode(val, keyIndex+1, maxDepth, keys)
}
} else {
continue
}
}
return &yaml.Node{}, nil
}
// FindNode returns a node object pointing to the given token in a yaml file. The node contains
//information such as the string value, line number, bordering commments, etc.
func FindNode(filename string, keys []string, token string) (*yaml.Node, error) {
data, _ := ioutil.ReadFile(filename)
var node yaml.Node
err := yaml.Unmarshal(data, &node)
if err != nil {
fmt.Printf("%+v", err)
}
keys = append(keys, token)
return findNode(node.Content[0], 0, len(keys)-1, keys)
}