mirror of
https://github.com/mikefarah/yq.git
synced 2026-08-25 00:44:43 +08:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e95ebebf | ||
|
|
ed5685319d | ||
|
|
554eb998f6 |
@@ -16,7 +16,7 @@ func (o *CandidateNode) goccyDecodeIntoChild(childNode ast.Node, cm yaml.Comment
|
||||
return newChild, err
|
||||
}
|
||||
|
||||
func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap) error {
|
||||
func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap, anchorMap map[string]*CandidateNode) error {
|
||||
log.Debugf("UnmarshalYAML %v", node)
|
||||
log.Debugf("UnmarshalYAML %v", node.Type().String())
|
||||
log.Debugf("UnmarshalYAML Node Value: %v", node.String())
|
||||
@@ -49,6 +49,13 @@ func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap) er
|
||||
|
||||
}
|
||||
}
|
||||
o.Anchor = node.
|
||||
|
||||
if o.Anchor != "" {
|
||||
anchorMap[o.Anchor] = o
|
||||
}
|
||||
|
||||
if o.Ali
|
||||
|
||||
o.Value = node.String()
|
||||
switch node.Type() {
|
||||
@@ -92,7 +99,7 @@ func (o *CandidateNode) UnmarshalGoccyYAML(node ast.Node, cm yaml.CommentMap) er
|
||||
// to solve the multiline > problem
|
||||
o.Value = astLiteral.Value.Value
|
||||
case ast.TagType:
|
||||
if err := o.UnmarshalGoccyYAML(node.(*ast.TagNode).Value, cm); err != nil {
|
||||
if err := o.UnmarshalGoccyYAML(node.(*ast.TagNode).Value, cm, anchorMap); err != nil {
|
||||
return err
|
||||
}
|
||||
o.Tag = node.(*ast.TagNode).Start.Value
|
||||
|
||||
@@ -3,15 +3,21 @@
|
||||
package yqlib
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"regexp"
|
||||
|
||||
yaml "github.com/goccy/go-yaml"
|
||||
"github.com/goccy/go-yaml/ast"
|
||||
)
|
||||
|
||||
type goccyYamlDecoder struct {
|
||||
decoder yaml.Decoder
|
||||
cm yaml.CommentMap
|
||||
decoder yaml.Decoder
|
||||
cm yaml.CommentMap
|
||||
bufferRead bytes.Buffer
|
||||
readAnything bool
|
||||
anchorMap map[string]*CandidateNode
|
||||
}
|
||||
|
||||
func NewGoccyYAMLDecoder() Decoder {
|
||||
@@ -20,21 +26,40 @@ func NewGoccyYAMLDecoder() Decoder {
|
||||
|
||||
func (dec *goccyYamlDecoder) Init(reader io.Reader) error {
|
||||
dec.cm = yaml.CommentMap{}
|
||||
dec.decoder = *yaml.NewDecoder(reader, yaml.CommentToMap(dec.cm), yaml.UseOrderedMap())
|
||||
dec.readAnything = false
|
||||
dec.anchorMap = make(map[string]*CandidateNode)
|
||||
readerToUse := io.TeeReader(reader, &dec.bufferRead)
|
||||
dec.decoder = *yaml.NewDecoder(readerToUse, yaml.CommentToMap(dec.cm), yaml.UseOrderedMap())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dec *goccyYamlDecoder) Decode() (*CandidateNode, error) {
|
||||
|
||||
var commentLineRegEx = regexp.MustCompile(`^\s*#`)
|
||||
|
||||
var ast ast.Node
|
||||
|
||||
err := dec.decoder.Decode(&ast)
|
||||
if err != nil {
|
||||
if errors.Is(err, io.EOF) && !dec.readAnything {
|
||||
|
||||
content := dec.bufferRead.String()
|
||||
// only null fix
|
||||
if content == "null" || content == "~" {
|
||||
dec.readAnything = true
|
||||
return createScalarNode(nil, content), nil
|
||||
} else if commentLineRegEx.MatchString(content) {
|
||||
dec.readAnything = true
|
||||
node := createScalarNode(nil, "")
|
||||
node.LeadingContent = content
|
||||
return node, nil
|
||||
}
|
||||
return nil, err
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
candidateNode := &CandidateNode{}
|
||||
if err := candidateNode.UnmarshalGoccyYAML(ast, dec.cm); err != nil {
|
||||
if err := candidateNode.UnmarshalGoccyYAML(ast, dec.cm, dec.anchorMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -19,6 +19,12 @@ var yamlFormatScenarios = []formatScenario{
|
||||
input: "~",
|
||||
expected: "~\n",
|
||||
},
|
||||
{
|
||||
description: "comment",
|
||||
skipDoc: true,
|
||||
input: "# cat",
|
||||
expected: "# cat\n",
|
||||
},
|
||||
{
|
||||
description: "octal",
|
||||
skipDoc: true,
|
||||
@@ -32,6 +38,13 @@ var yamlFormatScenarios = []formatScenario{
|
||||
input: "[null]",
|
||||
expected: "[null]\n",
|
||||
},
|
||||
{
|
||||
description: "simple anchor map",
|
||||
skipDoc: true,
|
||||
input: "a: &remember mike\nb: *remember",
|
||||
expression: "explode(.)",
|
||||
expected: "a: mike\nb: mike\n",
|
||||
},
|
||||
{
|
||||
description: "multi document anchor map",
|
||||
skipDoc: true,
|
||||
@@ -100,7 +113,7 @@ var yamlParseScenarios = []expressionScenario{
|
||||
}
|
||||
|
||||
func testYamlScenario(t *testing.T, s formatScenario) {
|
||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(NewDefaultYamlPreferences()), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description)
|
||||
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewGoccyYAMLDecoder(), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description)
|
||||
}
|
||||
|
||||
func TestYamlParseScenarios(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user