package main import ( "fmt" "github.com/goccy/go-yaml" "github.com/spf13/cobra" "os" "reflect" ) type MyMap yaml.MapSlice func (m *MyMap) Set(key any, value any) { for i := range len(*m) { if (*m)[i].Key == key { (*m)[i].Value = value return } } *m = append(*m, yaml.MapItem{Key: key, Value: value}) } func (m MyMap) Get(key any) any { for _, item := range m { if item.Key == key { return item.Value } } return nil } func mergeMap(yaml1 yaml.MapSlice, yaml2 yaml.MapSlice) yaml.MapSlice { res := MyMap(yaml1) for _, item := range yaml2 { initialValue := res.Get(item.Key) value := item.Value switch { case initialValue != nil: if reflect.TypeOf(initialValue) == reflect.TypeOf(yaml.MapSlice{}) && reflect.TypeOf(value) == reflect.TypeOf(yaml.MapSlice{}) { mergedMap := mergeMap(initialValue.(yaml.MapSlice), value.(yaml.MapSlice)) res.Set(item.Key, mergedMap) } else { res.Set(item.Key, item.Value) } default: res.Set(item.Key, item.Value) } } return yaml.MapSlice(res) } func merge(cmd *cobra.Command, args []string) error { res := make(yaml.MapSlice, 0) for _, arg := range args { config, err := parse(read(arg)) if err != nil { return fmt.Errorf("%s: %w", arg, err) } res = mergeMap(res, config) } encode(os.Stdout, res) return nil }