102 lines
1.8 KiB
Go
102 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
var (
|
|
input = stringsArray{}
|
|
output = ""
|
|
replaceArrays = false
|
|
outType = "yaml"
|
|
)
|
|
|
|
func main() {
|
|
flag.Var(&input, "i", "input files")
|
|
flag.StringVar(&output, "o", "out.yaml", "output file")
|
|
flag.BoolVar(&replaceArrays, "replace_arrays", false, "replace arrays with same keys. Merge otherwise.")
|
|
flag.StringVar(&outType, "out_type", "yaml", "output type, 'yaml' (default) or 'json'")
|
|
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()
|
|
|
|
var enc Encoder
|
|
switch outType {
|
|
case "yaml":
|
|
enc = yaml.NewEncoder(fp)
|
|
case "json":
|
|
enc = json.NewEncoder(fp)
|
|
default:
|
|
panic(fmt.Errorf("unknown output type: %s", outType))
|
|
}
|
|
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, ",")
|
|
}
|
|
|
|
type Encoder interface {
|
|
Encode(any) error
|
|
}
|