89 lines
1.6 KiB
Go
89 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"os"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
var (
|
|
input = stringsArray{}
|
|
output = ""
|
|
indent = 2
|
|
replaceArrays = false
|
|
)
|
|
|
|
func main() {
|
|
flag.Var(&input, "i", "input files")
|
|
flag.StringVar(&output, "o", "out.yaml", "output file")
|
|
flag.IntVar(&indent, "indent", 2, "changes the used indentation used when encoding")
|
|
flag.BoolVar(&replaceArrays, "replace_arrays", false, "replace arrays with same keys. Merge otherwise.")
|
|
flag.Parse()
|
|
|
|
result := map[string]any{}
|
|
|
|
for _, inputFile := range input {
|
|
b, err := os.ReadFile(inputFile)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
m := map[string]any{}
|
|
if err := yaml.Unmarshal(b, m); err != nil {
|
|
panic(err)
|
|
}
|
|
merge(result, m, replaceArrays)
|
|
}
|
|
|
|
fp, err := os.Create(output)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer fp.Close()
|
|
|
|
enc := yaml.NewEncoder(fp)
|
|
enc.SetIndent(indent)
|
|
if err := enc.Encode(result); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func merge(target map[string]any, in map[string]any, replaceArrays bool) {
|
|
for k, v := range in {
|
|
old, exist := target[k]
|
|
if !exist {
|
|
target[k] = v
|
|
continue
|
|
}
|
|
switch old := old.(type) {
|
|
case map[string]any:
|
|
v, ok := v.(map[string]any)
|
|
if ok {
|
|
merge(old, v, replaceArrays)
|
|
target[k] = old
|
|
continue
|
|
}
|
|
case []any:
|
|
v, ok := v.([]any)
|
|
if ok && !replaceArrays {
|
|
old = append(old, v...)
|
|
target[k] = old
|
|
continue
|
|
}
|
|
}
|
|
target[k] = v
|
|
}
|
|
}
|
|
|
|
type stringsArray []string
|
|
|
|
func (i *stringsArray) Set(value string) error {
|
|
*i = append(*i, value)
|
|
return nil
|
|
}
|
|
|
|
func (i *stringsArray) String() string {
|
|
return strings.Join(*i, ",")
|
|
}
|