aboutsummaryrefslogblamecommitdiff
path: root/main.go
blob: b41afa496dd4e7b88ec8bdaa852fe86332186986 (plain) (tree)























































































                                                                                                                
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, ",")
}