Go: Как сохранить Root отступ в yaml? - PullRequest
0 голосов
/ 05 августа 2020

У меня возникли проблемы при перекодировании файла YAML с go и yaml.v3. В основном у меня есть файл YAML, для которого отступ root равен 6 (root отступ на 6 пробелов).

Мне нужно прочитать этот файл, затем изменить несколько значений и переписать файл, однако при переписывании структуры YAML в файл я теряю этот отступ. Есть идеи, как я могу этого добиться? в противном случае я, вероятно, перечитаю файл как текстовый и добавлю отступ.

Ниже приведен код, который я использую.

Отрывок из файла YAML:

      doc:
        a: 'default'
        b: 42
        c: 3
        structure: 'flat'

     
      use_timezone: ''
      kafka_nodes: 3
      

Анализ файла YAML и обратная запись в файл

var ymlConfig yaml.Node
err = yaml.Unmarshal([]byte(pullConfig()), &ymlConfig)
//code ommited for brievity (some value verification and modification)

file, err := os.OpenFile("config.yml", os.O_WRONLY, os.ModeAppend)
if err != nil {
    panic(err)
}
defer file.Close()

d := yaml.NewEncoder(file)
d.SetIndent(4)// tried changing the indent but it does not change the root
defer d.Close()


if err := d.Encode(&ymlConfig); err != nil {
    panic(err)
}

Результат перекодирования

doc:
  a: 'default'
  b: 42
  c: 3
  structure: 'flat'

     
use_timezone: ''
kafka_nodes: 3
      

1 Ответ

1 голос
/ 05 августа 2020

Вы можете сделать что-нибудь столь же простое, как это.

package main

import (
    "bytes"
    "fmt"
    "gopkg.in/yaml.v3"
)

func addRootIndent(b []byte, n int) []byte {
    prefix := append([]byte("\n"), bytes.Repeat([]byte(" "), n)...)
    b = append(prefix[1:], b...)  // Indent first line
    return bytes.ReplaceAll(b, []byte("\n"), prefix)
}

func main() {
    t := struct {
        Doc map[string]interface{}
    } {
        Doc: map[string]interface{}{
            "a": "The meaning is...",
            "b": 42,
        },
    }

    b, _ := yaml.Marshal(t)
    b = addRootIndent(b, 6)

    fmt.Println(string(b))
}

Чтобы изменить отступ в yaml do c, используйте

func (e *Encoder) SetIndent(spaces int)
...