Ray*_*n D 8 json yaml abstract-syntax-tree go
我最近看到go yaml lib具有新版本(V3)
具有节点功能(在我看来,这是一个杀手级功能:)),它可以在不更改文件结构的情况下帮助大量修改yaml
但是由于它是相当新的(从上周开始),所以我没有找到一些有用的文档和所需的上下文示例(添加新的对象/节点并在不删除注释的情况下保持文件结构不变)等。
我需要的是操作yaml文件
例如
可以说我有这个yaml文件
version: 1
type: verbose
kind : bfr
# my list of applications
applications:
- name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
Run Code Online (Sandbox Code Playgroud)
现在,我有一个json对象(例如带有app2),需要将其插入到现有文件中
[
{
"comment: "Second app",
"name": "app2",
"kind": "golang",
"path": "app2",
"exec": {
"platforms": "dockerh",
"builder": "test"
}
}
]
Run Code Online (Sandbox Code Playgroud)
我需要在第一个应用程序之后将其添加到yml文件中(应用程序是应用程序的数组)
version: 1
type: verbose
kind : bfr
# my list of applications
applications:
# First app
- name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
# Second app
- name: app2
kind: golang
path: app2
exec:
platforms: dockerh
builder: test
Run Code Online (Sandbox Code Playgroud)
是否可以从yaml文件中添加新的json对象?也删除现有的
我也找到了这个博客 https://blog.ubuntu.com/2019/04/05/api-v3-of-the-yaml-package-for-go-is-available
这是代表对象的类型
type VTS struct {
version string `yaml:"version"`
types string `yaml:"type"`
kind string `yaml:"kind,omitempty"`
apps Applications `yaml:"applications,omitempty"`
}
type Applications []struct {
Name string `yaml:"name,omitempty"`
Kind string `yaml:"kind,omitempty"`
Path string `yaml:"path,omitempty"`
Exec struct {
Platforms string `yaml:"platforms,omitempty"`
Builder string `yaml:"builder,omitempty"`
} `yaml:"exec,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
更新
测试了wiil7200 我提供的解决方案后,发现了2个问题
我用最后写到文件
err = ioutil.WriteFile("output.yaml", b, 0644)
和yaml输出有2个问题。
应用程序的数组从注释开始,应该从名称开始
name输入后,该kind属性和之后的所有其他属性均未与name
知道如何解决那些问题吗?考虑到这个comments问题,可以说我是从其他属性而不是从json获得的(如果它使它更简单)
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
- # test 1
name: app2
kind: golang
path: app2
exec:
platform: dockerh
builder: test
Run Code Online (Sandbox Code Playgroud)
首先,让我开始说使用yaml.Node从有效yaml编组时不会产生有效的yaml,如以下示例所示。可能应该提出问题。
package main
import (
"fmt"
"log"
"gopkg.in/yaml.v3"
)
var (
sourceYaml = `version: 1
type: verbose
kind : bfr
# my list of applications
applications:
# First app
- name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
`
)
func main() {
t := yaml.Node{}
err := yaml.Unmarshal([]byte(sourceYaml), &t)
if err != nil {
log.Fatalf("error: %v", err)
}
b, err := yaml.Marshal(&t)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
Run Code Online (Sandbox Code Playgroud)
在go版本go1.12.3 windows / amd64中产生以下无效的Yaml
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
Run Code Online (Sandbox Code Playgroud)
其次,使用诸如
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
Run Code Online (Sandbox Code Playgroud)
从ubuntu的博客和源文档中可以看出,它可以正确识别结构中的节点(分别是节点)并分别构建该树,但事实并非如此。取消编组时,它将提供正确的节点树,但是重新编组时,它将产生以下yaml,其中包含yaml.Node公开的所有字段。可悲的是我们不能走这条路,必须找到另一条路。
version: "1"
type: verbose
kind: bfr
applications:
kind: 2
style: 0
tag: '!!seq'
value: ""
anchor: ""
alias: null
content:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
headcomment: ""
linecomment: ""
footcomment: ""
line: 9
column: 3
Run Code Online (Sandbox Code Playgroud)
现在,我们可以忽略结构中yaml.Nodes的第一个问题和程序错误(位于gopkg.in/yaml.v3 v3.0.0-20190409140830-cdc409dda467上),我们可以开始处理程序包公开的Nodes。不幸的是,没有可以轻松添加节点的抽象,因此用途可能会有所不同,并且标识节点可能会很麻烦。反思可能会对您有所帮助,因此我将其作为练习留给您。
您会发现注释spew.Dump以一种不错的格式转储了整个节点Tree,这有助于在将Nodes添加到源代码树时进行调试。
当然,您也可以删除节点,您只需要确定需要删除的特定节点即可。您只需确保删除父节点(如果它们是图或序列)即可。
type VTS struct {
Version string `yaml:"version" json:"version"`
Types string `yaml:"type" json:"type"`
Kind string `yaml:"kind,omitempty" json:"kind,omitempty"`
Apps yaml.Node `yaml:"applications,omitempty" json:"applications,omitempty"`
}
Run Code Online (Sandbox Code Playgroud)
生产yaml
version: 1
type: verbose
kind: bfr
# my list of applications
applications:
- # First app
name: app1
kind: nodejs
path: app1
exec:
platforms: k8s
builder: test
- # Second app
name: app2
kind: golang
path: app2
exec:
platform: dockerh
builder: test
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1476 次 |
| 最近记录: |