diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 88 |
1 files changed, 88 insertions, 0 deletions
@@ -0,0 +1,88 @@ +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, ",") +} |