私は最近、go yaml libに新しいバージョン(V3)があることを確認しました
nodes 機能(私の意見ではキラー機能です:))を使用すると、ファイルの構造を変更せずに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
_
今私は既存のファイルに挿入する必要があるjsonオブジェクト(例えば_app2
_付き)を取得しました
_[
{
"comment: "Second app",
"name": "app2",
"kind": "golang",
"path": "app2",
"exec": {
"platforms": "dockerh",
"builder": "test"
}
}
]
_
最初のアプリケーションの後にymlファイルに追加する必要があります(applicationsはアプリケーションの配列です)
_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
_
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"`
}
_
更新
_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
_
前のノードを削除せずに、新しいノードを作成してコンテンツに直接追加できます。次の例は、この点を示しています。
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
`
)
type Application struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Kind string `yaml:"kind,omitempty" json:"kind,omitempty"`
Path string `yaml:"path,omitempty" json:"path,omitempty"`
Exec struct {
Platforms string `yaml:"platforms,omitempty" json:"platforms,omitempty"`
Builder string `yaml:"builder,omitempty" json:"builder,omitempty"`
} `yaml:"exec,omitempty" json:"exec,omitempty"`
}
func newApplicationNode(
name string,
kind string,
path string,
platforms string,
builder string,
comment string) (*yaml.Node, error) {
app := Application{
Name: name,
Kind: kind,
Path: path,
Exec: struct {
Platforms string `yaml:"platforms,omitempty" json:"platforms,omitempty"`
Builder string `yaml:"builder,omitempty" json:"builder,omitempty"`
}{platforms, builder},
}
marshalledApp, err := yaml.Marshal(&app)
if err != nil {
return nil, err
}
node := yaml.Node{}
if err := yaml.Unmarshal(marshalledApp, &node); err != nil {
return nil, err
}
node.Content[0].HeadComment = comment
return &node, nil
}
func main() {
yamlNode := yaml.Node{}
err := yaml.Unmarshal([]byte(sourceYaml), &yamlNode)
if err != nil {
log.Fatalf("error: %v", err)
}
newApp, err := newApplicationNode("app2", "golang", "app2", "dockerh",
"test", "Second app")
if err != nil {
log.Fatalf("error: %v", err)
}
appIdx := -1
for i, k := range yamlNode.Content[0].Content {
if k.Value == "applications" {
appIdx = i + 1
break
}
}
yamlNode.Content[0].Content[appIdx].Content = append(
yamlNode.Content[0].Content[appIdx].Content, newApp.Content[0])
out, err := yaml.Marshal(&yamlNode)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
明らかに、私がnewApplicationNode
で行ったようなハッキーな方法をとるのではなく、JSONから適切に非整列化できます。ただし、前の回答で述べたように、キーと実際の値はContent
内の後続のインデックスにあることに注意することが重要です。そのため、ドキュメントを変更するときにこれを考慮する必要があります。 (たとえば、applications
キーを検索しますが、次のインデックス(appIdx = i + 1
(私の例では)その内容について。
お役に立てば幸いです。