diff options
-rw-r--r-- | go.mod | 5 | ||||
-rw-r--r-- | go.sum | 3 | ||||
-rw-r--r-- | main.go | 88 | ||||
-rw-r--r-- | readme.md | 78 |
4 files changed, 174 insertions, 0 deletions
@@ -0,0 +1,5 @@ +module go.neonxp.ru/merger + +go 1.22.2 + +require gopkg.in/yaml.v3 v3.0.1 @@ -0,0 +1,3 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -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, ",") +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..09122e9 --- /dev/null +++ b/readme.md @@ -0,0 +1,78 @@ +# merger + +Простейший мерджер yaml'ов + +## Установка + +``` +go install go.neonxp.ru/merger@latest +``` + +## Использование + +``` +merger -i file1.yaml -i file2.yaml -i fileN.yaml -o output.yaml +``` + +Есть ещё ключи: + +- `-indent 2` устанавливает отступ в результирующем yaml'е +- `-replace_arrays false` - если true то массивы по одинаковым ключам будут перезатираться. По умолчанию - соединяться. + +## Пример + +file1.yaml +```yaml +a1: + a11: + - one + - two + a12: "one" +a2: + a21: + - one + - two + a22: "one" + a23: + a231: 231 + a232: 232 + a233: 233 +``` + +file2.yaml +```yaml +a1: + a11: + - three + - four + a12: "two" +a2: + a23: + a231: "!!!" + a232: "???" + a233: + sub: tree + to: merge +``` + +output.yaml +```yaml +a1: + a11: + - one + - two + - three + - four + a12: two +a2: + a21: + - one + - two + a22: one + a23: + a231: '!!!' + a232: ??? + a233: + sub: tree + to: merge +```
\ No newline at end of file |