Имитация патч-слияния в структурах go, прочитанных из файлов yaml - PullRequest
0 голосов
/ 13 марта 2019

Учитывая ямлы, как показано ниже:

default.yaml

services:
  A:
    host: "google.com"
    path: "search"
    scheme: "https"
  B:
    host: "bing.com"
    path: "find"
logging:
  level: WARN

staging.yaml

services:
  A:
    path: "search2"

Я хочу этот объединенный yaml:

services:
  A:
    host: "google.com"
    path: "search2"
    scheme: "https"
  B:
    host: "bing.com"
    path: "find"
logging:
  level: WARN

Есть ли способ достичь такого поведения слияния / исправления в go? Я играю с mergo, но в настоящее время он преобразует services["A"].host и services["A"].scheme в nil или "" в представлении объединенного объекта в зависимости от того, является ли соответствующее поле структуры значением или указателем.

import (
    "io/ioutil"
    "path"

    "github.com/imdario/mergo"
    "gopkg.in/yaml.v2"
)

type Logging struct {
    Level *string `json:"level,omitempty" yaml:"level,omitempty"`
}

type Service struct {
    Host     *string `json:"host,omitempty" yaml:"host,omitempty"`
    Path     *string `json:"path,omitempty" yaml:"path,omitempty"`
    Scheme   *string `json:"scheme,omitempty" yaml:"scheme,omitempty"`
    Schedule *string `json:"schedule,omitempty" yaml:"schedule,omitempty"`
    Count    *int    `json:"count,omitempty" yaml:"count,omitempty"`
}

type Config struct {
    Services map[string]Service `json:"services,omitempty" yaml:"services,omitempty"`
    Logging  *Logging           `json:"logging,omitempty" yaml:"logging,omitempty"`
}

// error handling omitted for brevity
func main() {
    var defc Config
    yamlFile, _ := ioutil.ReadFile("default.yaml"))
    _ = yaml.Unmarshal(yamlFile, &defc)

    var envc Config
    yamlFile, _ = ioutil.ReadFile("staging.yaml"))
    _ = yaml.Unmarshal(yamlFile, &envc)

    _ = mergo.Merge(&defc, envc, mergo.WithOverride)
}

Мотивация - поддерживать специфичные для env файлы yaml, которые содержат различные конфигурации. Я хочу сохранить базовый yaml (default.yaml), который определяет всю конфигурацию, а затем для каждой среды (dev / staging / prod ...) определить только delta в этих yamls, чтобы все оставалось СУХИМЫМ .

Чтобы получить эквивалент от js / node, это примерно то, что я ищу: https://runkit.com/embed/j9xi2bu00a74

...