如何在yaml包的Go和API v3中生成配置文件时对注释进行编码

如何在yaml包的Go和API v3中生成配置文件时对注释进行编码,go,yaml,Go,Yaml,我试图学习在封送结构以配置YAML时使用YAML v3 注意:更新:我最初的示例有点过于简化。我的实际要求如下: 例如,我有: package main import ( "fmt" "io/ioutil" "gopkg.in/yaml.v3" ) type Ec2 struct { Class string `yaml:"class"` Ip string `yaml:"ip"` } type Vpc struct { Subnet

我试图学习在封送结构以配置YAML时使用YAML v3

注意:更新:我最初的示例有点过于简化。我的实际要求如下:

例如,我有:

package main

import (
    "fmt"
    "io/ioutil"

    "gopkg.in/yaml.v3"
)

type Ec2 struct {
    Class string `yaml:"class"`
    Ip    string `yaml:"ip"`
}

type Vpc struct {
    Subnet string `yaml:"subnet"`
    Igw    interface{} `yaml:"igw"`

}

type Config struct {
    Ec2 Ec2 `yaml:"ec2"`
    Vpc Vpc `yaml:"vpc"`
}

func main() {
    c := Config{}
    bytes, err := yaml.Marshal(c)
    if err != nil {
        fmt.Println(err)
    }

    ioutil.WriteFile("config.yaml", bytes, 0644)
}
pwd
中创建名为
config.yaml
的文件,如:

  ec2:
    class: ""
    ip: ""
  vpc:
    subnet: ""
    igw: null
但我正在尝试生成配置文件(在本例中为config.yaml),如下所示:


使用
V.3
可以实现这一点吗?

有两种方法可以利用
yaml.v3
及其注释功能:

  • 手动构建
    yaml.Node
    树(繁琐的维护;精确的值更新)
  • 将模板解析为
    yaml.Node
    树(易于维护;更难更新值)

方法1:

手工制作YAML节点树:

config = &yaml.Node{
    Kind: yaml.DocumentNode,
    Content: []*yaml.Node{
        &yaml.Node{
            Kind: yaml.MappingNode,
            Content: []*yaml.Node{
                &yaml.Node{
                    Kind:        yaml.ScalarNode,
                    Value:       "ec2",
                    HeadComment: "# This section is for EC2",
                },
                &yaml.Node{
                    Kind:  yaml.ScalarNode,
                    Style: yaml.DoubleQuotedStyle,
                    Value: "", // <- field value goes here
                },

                &yaml.Node{
                    Kind:        yaml.ScalarNode,
                    Value:       "vpc",
                    HeadComment: "# This section is for VPC",
                },
                &yaml.Node{
                    Kind:  yaml.ScalarNode,
                    Style: yaml.DoubleQuotedStyle,
                    Value: "", // <- field value goes here
                },
            },
        },
    },
}

方法2:

阅读YAML模式的模板,例如

var yamlSchema = []byte(`

# EC2 header-comment
ec2: ""

# This section is for VPC
vpc: ""

`)
# This section is for EC2
ec2: ""          # <-- place user input here
# footer EC2

# This section is for VPC
vpc: ""
然后在运行时将其解析为
yaml.Node
树,如下所示:

var c yaml.Node
err := yaml.Unmarshal(yamlSchema, &c)
但是作为一个
yaml.Node
树,它有嵌套的
yaml.Node
s片段,您需要以编程方式查找字段值,以便在封送配置以进行写入时,将这些值与正确的字段配对

例如,这可能在今天起作用:

c.Content[0].Content[1].Value = ec2Value // dangerous
但不是明天,当模式改变时

遍历映射并查找字段值
ec2
,然后将其值放置在相邻节点中是正确的方法

显示如何将页眉/页脚/内联注释添加到架构中,例如

var yamlSchema = []byte(`

# EC2 header-comment
ec2: ""

# This section is for VPC
vpc: ""

`)
# This section is for EC2
ec2: ""          # <-- place user input here
# footer EC2

# This section is for VPC
vpc: ""
#本节适用于EC2

ec2:“#下面的答案是否说明了您想要实现的目标?我更愿意遵循方法1。但是我很难建造这棵树。在我的示例中,我过度简化了结构。我的实际结构有点复杂,其中嵌套了结构类型Config struct{Ec2 Ec2 yaml:“Ec2”Vpc yaml:“Vpc”}类型Ec2 struct{Class string yaml:“Class”IP string yaml:“IP”}类型Vpc struct{Subnet string yaml:“Subnet”…}``我想对所有这些字段进行注释。我可以使用节点类型来实现这一点吗?我更喜欢使用方法1。但是我很难建造这棵树。在我的示例中,我过度简化了
结构
。我的实际结构有点复杂,其中嵌套了结构键入Config struct{Ec2 Ec2
yaml:“Ec2”
Vpc-Vpc
yaml:“Vpc”
}键入Ec2 struct{Class string
yaml:“Class”
IP string
yaml:“IP”
}键入Vpc结构{Subnet string
yaml:“Subnet”
.}`,我想对所有这些字段进行注释。我可以使用节点类型来完成吗?