-
Notifications
You must be signed in to change notification settings - Fork 78
/
yaml.go
149 lines (138 loc) · 3.56 KB
/
yaml.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package yaml
import (
"bytes"
"fmt"
"io"
"os"
"reflect"
"github.com/goccy/go-yaml"
"github.com/goccy/go-yaml/ast"
"github.com/goccy/go-yaml/parser"
yamlv3 "gopkg.in/yaml.v3"
)
// Parse yaml data by file name
func ParseYamlFromFile(filename string, target interface{}) error {
content, err := os.ReadFile(filename)
if err != nil {
return err
}
err = yamlv3.Unmarshal(content, target)
if err != nil {
return err
}
return nil
}
// Read specify document by filterKind from specify file,
// return first document when filterKind is empty
func File2Document(filename string, filterKind string) *ast.DocumentNode {
file, err := parser.ParseFile(filename, 0)
if err != nil || len(file.Docs) == 0 {
return nil
}
if filterKind == "" {
return file.Docs[0]
} else {
for _, doc := range file.Docs {
docKind, err := GetByPathString(doc, "$.kind")
if err != nil {
continue
}
if docKind == filterKind {
return doc
}
}
return nil
}
}
// Convert yaml string to []ast.Document
func YAML2Documents(yamlContent string) ([]*ast.DocumentNode, error) {
// parser documents from yaml
file, err := parser.ParseBytes([]byte(yamlContent), 0)
if err != nil {
return nil, err
}
return file.Docs, nil
}
// Get specify node string from yaml by path string
func GetByPathString(doc io.Reader, path string) (string, error) {
var result string
p, err := yaml.PathString(path)
if err != nil {
return "", fmt.Errorf("unable build path by %s: %v", path, err)
}
err = p.Read(doc, &result)
if err != nil {
return "", fmt.Errorf("unable read by path %s: %v", path, err)
}
return result, nil
}
// Get specify node string from yaml by path string, panic if occur error
func MustGetByPathString(doc io.Reader, path string) string {
var result string
p, err := yaml.PathString(path)
if err != nil {
panic(fmt.Sprintf("unable build path by %s: %v", path, err))
}
err = p.Read(doc, &result)
if err != nil {
panic(fmt.Sprintf("unable build path by %s: %v", path, err))
}
return result
}
// Get specify node string from yaml by path, panic if occur error
func GetByPath(doc io.Reader, path *yaml.Path) (string, error) {
expectNode, err := path.ReadNode(doc)
if err != nil {
return "", fmt.Errorf("unable read by path %s: %v", path, err)
}
if stringNode, ok := expectNode.(*ast.StringNode); ok {
return stringNode.Value, nil
}
return expectNode.String(), nil
}
// Get specify node string from yaml by path, panic if occur error
func MustGetByPath(doc io.Reader, path *yaml.Path) string {
expectNode, err := path.ReadNode(doc)
if err != nil {
panic(fmt.Sprintf("unable get value by path: %v", path))
}
if stringNode, ok := expectNode.(*ast.StringNode); ok {
return stringNode.Value
}
return expectNode.String()
}
// Merge multiple yaml documents into a single string,
// separate yaml documents with '---'
func MergeToOneYAML(yamlList ...interface{}) string {
if len(yamlList) == 0 {
return ""
}
var result bytes.Buffer
e := yamlv3.NewEncoder(&result)
for _, y := range yamlList {
if y == nil || reflect.ValueOf(y).IsNil() {
y = nil
}
e.SetIndent(2)
err := e.Encode(y)
if err != nil {
panic(err)
}
}
err := e.Close()
if err != nil {
panic(err)
}
return result.String()
}
// Merge multiple yaml string into a single string,
// separate yaml documents with '---'
func MergeStringsToOneYAML(yamlList []string) string {
documents := []interface{}{}
for _, y := range yamlList {
document := map[string]interface{}{}
yamlv3.Unmarshal([]byte(y), document)
documents = append(documents, document)
}
return MergeToOneYAML(documents...)
}