mirror of
https://github.com/goccy/go-yaml.git
synced 2025-12-08 06:09:57 +00:00
Skip directive in path operations (#758)
This commit is contained in:
parent
7901e98f54
commit
0040ab4161
2 changed files with 101 additions and 1 deletions
10
path.go
10
path.go
|
|
@ -258,6 +258,10 @@ func (p *Path) Filter(target, v interface{}) error {
|
||||||
// FilterFile filter from ast.File by YAMLPath.
|
// FilterFile filter from ast.File by YAMLPath.
|
||||||
func (p *Path) FilterFile(f *ast.File) (ast.Node, error) {
|
func (p *Path) FilterFile(f *ast.File) (ast.Node, error) {
|
||||||
for _, doc := range f.Docs {
|
for _, doc := range f.Docs {
|
||||||
|
// For simplicity, directives cannot be the target of operations
|
||||||
|
if doc.Body != nil && doc.Body.Type() == ast.DirectiveType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
node, err := p.FilterNode(doc.Body)
|
node, err := p.FilterNode(doc.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -352,6 +356,10 @@ func (p *Path) ReplaceWithFile(dst *ast.File, src *ast.File) error {
|
||||||
// ReplaceNode replace ast.File with ast.Node.
|
// ReplaceNode replace ast.File with ast.Node.
|
||||||
func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
|
func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
|
||||||
for _, doc := range dst.Docs {
|
for _, doc := range dst.Docs {
|
||||||
|
// For simplicity, directives cannot be the target of operations
|
||||||
|
if doc.Body != nil && doc.Body.Type() == ast.DirectiveType {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if node.Type() == ast.DocumentType {
|
if node.Type() == ast.DocumentType {
|
||||||
node = node.(*ast.DocumentNode).Body
|
node = node.(*ast.DocumentNode).Body
|
||||||
}
|
}
|
||||||
|
|
@ -364,7 +372,7 @@ func (p *Path) ReplaceWithNode(dst *ast.File, node ast.Node) error {
|
||||||
|
|
||||||
// AnnotateSource add annotation to passed source ( see section 5.1 in README.md ).
|
// AnnotateSource add annotation to passed source ( see section 5.1 in README.md ).
|
||||||
func (p *Path) AnnotateSource(source []byte, colored bool) ([]byte, error) {
|
func (p *Path) AnnotateSource(source []byte, colored bool) ([]byte, error) {
|
||||||
file, err := parser.ParseBytes([]byte(source), 0)
|
file, err := parser.ParseBytes(source, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
92
path_test.go
92
path_test.go
|
|
@ -214,6 +214,82 @@ store:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPath_FilterFile(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
src string
|
||||||
|
expected any
|
||||||
|
expectedErr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple key",
|
||||||
|
path: "$.key",
|
||||||
|
src: `key: value`,
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "with directive",
|
||||||
|
path: "$.key",
|
||||||
|
src: `%YAML 1.2
|
||||||
|
---
|
||||||
|
key: value`,
|
||||||
|
expected: "value",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple docs",
|
||||||
|
path: "$.key2",
|
||||||
|
src: `key1: value1
|
||||||
|
---
|
||||||
|
key2: value2
|
||||||
|
`,
|
||||||
|
expected: "value2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
path, err := yaml.PathString(test.path)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error during path parsing: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := parser.ParseBytes([]byte(test.src), 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse YAML: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
node, err := path.FilterFile(file)
|
||||||
|
if test.expectedErr != "" {
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("expected error but got none")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), test.expectedErr) {
|
||||||
|
t.Fatalf("expected error containing %q but got %q", test.expectedErr, err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if node == nil {
|
||||||
|
t.Fatal("expected node but got nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var actual any
|
||||||
|
if err := yaml.Unmarshal([]byte(node.String()), &actual); err != nil {
|
||||||
|
t.Fatalf("failed to unmarshal result: %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(test.expected, actual) {
|
||||||
|
t.Fatalf("expected %v(%T) but got %v(%T)", test.expected, test.expected, actual, actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestPath_ReservedKeyword(t *testing.T) {
|
func TestPath_ReservedKeyword(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -605,6 +681,22 @@ b: 2
|
||||||
expected: `
|
expected: `
|
||||||
a: 3
|
a: 3
|
||||||
b: 2
|
b: 2
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "$.a",
|
||||||
|
dst: `
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
a: 1
|
||||||
|
b: 2
|
||||||
|
`,
|
||||||
|
src: `3`,
|
||||||
|
expected: `
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
a: 3
|
||||||
|
b: 2
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue