This commit is contained in:
Mike Farah 2023-04-13 14:34:34 +10:00
parent 1421a5a879
commit 08c93f0f1f
7 changed files with 106 additions and 21 deletions

View File

@ -174,6 +174,7 @@ func (n *CandidateNode) AsList() *list.List {
func (n *CandidateNode) GetValueRep() (interface{}, error) { func (n *CandidateNode) GetValueRep() (interface{}, error) {
// TODO: handle booleans, ints, etc // TODO: handle booleans, ints, etc
log.Debugf("GetValueRep for %v value: %v", n.GetNicePath(), n.Value)
realTag := n.guessTagFromCustomType() realTag := n.guessTagFromCustomType()
switch realTag { switch realTag {

View File

@ -78,59 +78,76 @@ func (o *CandidateNode) copyToYamlNode(node *yaml.Node) {
node.Column = o.Column node.Column = o.Column
} }
func (o *CandidateNode) decodeIntoChild(childNode *yaml.Node) (*CandidateNode, error) {
newChild := o.CreateChild()
// null yaml.Nodes to not end up calling UnmarshalYAML
// so we call it explicitly
if childNode.Tag == "!!null" {
newChild.Kind = ScalarNode
newChild.copyFromYamlNode(childNode)
return newChild, nil
}
err := childNode.Decode(newChild)
return newChild, err
}
func (o *CandidateNode) UnmarshalYAML(node *yaml.Node) error { func (o *CandidateNode) UnmarshalYAML(node *yaml.Node) error {
log.Debugf("unmarshalling %v", node.Tag) log.Debugf("UnmarshalYAML %v", node.Tag)
switch node.Kind { switch node.Kind {
case yaml.DocumentNode: case yaml.DocumentNode:
log.Debugf("UnmarshalYAML - a document")
o.Kind = DocumentNode o.Kind = DocumentNode
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
if len(node.Content) == 0 { if len(node.Content) == 0 {
return nil return nil
} }
singleChild := &CandidateNode{ singleChild, err := o.decodeIntoChild(node.Content[0])
Parent: o,
}
err := node.Content[0].Decode(singleChild)
if err != nil { if err != nil {
return err return err
} }
o.Content = []*CandidateNode{singleChild} o.Content = []*CandidateNode{singleChild}
return nil return nil
case yaml.AliasNode: case yaml.AliasNode:
log.Debug("decoding alias from yaml: %v", o.Tag) log.Debug("UnmarshalYAML - alias from yaml: %v", o.Tag)
o.Kind = AliasNode o.Kind = AliasNode
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
return nil return nil
case yaml.ScalarNode: case yaml.ScalarNode:
log.Debugf("its a scalar") log.Debugf("UnmarshalYAML - a scalar")
o.Kind = ScalarNode o.Kind = ScalarNode
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
return nil return nil
case yaml.MappingNode: case yaml.MappingNode:
log.Debugf("UnmarshalYAML - a mapping node")
o.Kind = MappingNode o.Kind = MappingNode
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
o.Content = make([]*CandidateNode, len(node.Content)) o.Content = make([]*CandidateNode, len(node.Content))
for i := 0; i < len(node.Content); i += 2 { for i := 0; i < len(node.Content); i += 2 {
keyNode := o.CreateChild()
keyNode.IsMapKey = true keyNode, err := o.decodeIntoChild(node.Content[i])
err := node.Content[i].Decode(keyNode)
if err != nil { if err != nil {
return err return err
} }
valueNode := o.CreateChild() keyNode.IsMapKey = true
valueNode.Key = keyNode
err = node.Content[i+1].Decode(valueNode) valueNode, err := o.decodeIntoChild(node.Content[i+1])
if err != nil { if err != nil {
return err return err
} }
valueNode.Key = keyNode
o.Content[i] = keyNode o.Content[i] = keyNode
o.Content[i+1] = valueNode o.Content[i+1] = valueNode
} }
return nil return nil
case yaml.SequenceNode: case yaml.SequenceNode:
log.Debugf("UnmarshalYAML - a sequence: %v", len(node.Content))
o.Kind = SequenceNode o.Kind = SequenceNode
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
o.Content = make([]*CandidateNode, len(node.Content)) o.Content = make([]*CandidateNode, len(node.Content))
@ -141,16 +158,17 @@ func (o *CandidateNode) UnmarshalYAML(node *yaml.Node) error {
keyNode.Kind = ScalarNode keyNode.Kind = ScalarNode
keyNode.Value = fmt.Sprintf("%v", i) keyNode.Value = fmt.Sprintf("%v", i)
valueNode := o.CreateChild() valueNode, err := o.decodeIntoChild(node.Content[i])
valueNode.Key = keyNode
err := node.Content[i].Decode(valueNode)
if err != nil { if err != nil {
return err return err
} }
valueNode.Key = keyNode
o.Content[i] = valueNode o.Content[i] = valueNode
} }
return nil return nil
case 0: case 0:
log.Debugf("UnmarshalYAML - errr.. %v", node.Tag)
// not sure when this happens // not sure when this happens
o.copyFromYamlNode(node) o.copyFromYamlNode(node)
return nil return nil

View File

@ -7,7 +7,7 @@ import (
) )
func (o *CandidateNode) MarshalJSON() ([]byte, error) { func (o *CandidateNode) MarshalJSON() ([]byte, error) {
log.Debugf("going to encode %v - %v", o.GetNicePath(), o.Tag) log.Debugf("MarshalJSON %v", NodeToString(o))
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
enc := json.NewEncoder(buf) enc := json.NewEncoder(buf)
enc.SetIndent("", " ") enc.SetIndent("", " ")
@ -15,12 +15,15 @@ func (o *CandidateNode) MarshalJSON() ([]byte, error) {
switch o.Kind { switch o.Kind {
case DocumentNode: case DocumentNode:
log.Debugf("MarshalJSON DocumentNode")
err := enc.Encode(o.Content[0]) err := enc.Encode(o.Content[0])
return buf.Bytes(), err return buf.Bytes(), err
case AliasNode: case AliasNode:
log.Debugf("MarshalJSON AliasNode")
err := enc.Encode(o.Alias) err := enc.Encode(o.Alias)
return buf.Bytes(), err return buf.Bytes(), err
case ScalarNode: case ScalarNode:
log.Debugf("MarshalJSON ScalarNode")
value, err := o.GetValueRep() value, err := o.GetValueRep()
if err != nil { if err != nil {
return buf.Bytes(), err return buf.Bytes(), err
@ -28,14 +31,13 @@ func (o *CandidateNode) MarshalJSON() ([]byte, error) {
err = enc.Encode(value) err = enc.Encode(value)
return buf.Bytes(), err return buf.Bytes(), err
case MappingNode: case MappingNode:
log.Debugf("MarshalJSON MappingNode")
buf.WriteByte('{') buf.WriteByte('{')
for i := 0; i < len(o.Content); i += 2 { for i := 0; i < len(o.Content); i += 2 {
log.Debugf("writing key %v", NodeToString(o.Content[i]))
if err := enc.Encode(o.Content[i].Value); err != nil { if err := enc.Encode(o.Content[i].Value); err != nil {
return nil, err return nil, err
} }
buf.WriteByte(':') buf.WriteByte(':')
log.Debugf("writing value %v", NodeToString(o.Content[i+1]))
if err := enc.Encode(o.Content[i+1]); err != nil { if err := enc.Encode(o.Content[i+1]); err != nil {
return nil, err return nil, err
} }
@ -45,8 +47,10 @@ func (o *CandidateNode) MarshalJSON() ([]byte, error) {
} }
buf.WriteByte('}') buf.WriteByte('}')
case SequenceNode: case SequenceNode:
log.Debugf("MarshalJSON SequenceNode")
err := enc.Encode(o.Content) err := enc.Encode(o.Content)
return buf.Bytes(), err return buf.Bytes(), err
} }
log.Debug("none of those things?")
return buf.Bytes(), nil return buf.Bytes(), nil
} }

View File

@ -49,7 +49,6 @@ func (d *dataTreeNavigator) GetMatchingNodes(context Context, expressionNode *Ex
log.Debug(NodeToString(el.Value.(*CandidateNode))) log.Debug(NodeToString(el.Value.(*CandidateNode)))
} }
} }
log.Debug("carr on>>")
handler := expressionNode.Operation.OperationType.Handler handler := expressionNode.Operation.OperationType.Handler
if handler != nil { if handler != nil {
return handler(d, context, expressionNode) return handler(d, context, expressionNode)

View File

@ -99,7 +99,7 @@ func (dec *yamlDecoder) Init(reader io.Reader) error {
func (dec *yamlDecoder) Decode() (*CandidateNode, error) { func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
var candidateNode CandidateNode var candidateNode CandidateNode
err := dec.decoder.Decode(&candidateNode) err := dec.decoder.Decode(&candidateNode)
log.Debugf("decoded the yaml")
if errors.Is(err, io.EOF) && dec.leadingContent != "" && !dec.readAnything { if errors.Is(err, io.EOF) && dec.leadingContent != "" && !dec.readAnything {
// force returning an empty node with a comment. // force returning an empty node with a comment.
dec.readAnything = true dec.readAnything = true

View File

@ -21,6 +21,9 @@ func yamlToJSON(sampleYaml string, indent int) string {
panic(err) panic(err)
} }
node := inputs.Front().Value.(*CandidateNode) node := inputs.Front().Value.(*CandidateNode)
log.Debugf("%v", NodeToString(node))
log.Debugf("Content[0] %v", NodeToString(node.Content[0]))
err = jsonEncoder.Encode(writer, node) err = jsonEncoder.Encode(writer, node)
if err != nil { if err != nil {
panic(err) panic(err)

60
pkg/yqlib/yaml_test.go Normal file
View File

@ -0,0 +1,60 @@
package yqlib
import (
"testing"
"github.com/mikefarah/yq/v4/test"
)
var yamlScenarios = []formatScenario{
// {
// description: "basic - null",
// skipDoc: true,
// input: "null",
// expected: "null\n",
// },
{
description: "basic - ~",
skipDoc: true,
input: "~",
expected: "~\n",
},
// {
// description: "basic - [null]",
// skipDoc: true,
// input: "[null]",
// expected: "[null]\n",
// },
// {
// description: "basic - [~]",
// skipDoc: true,
// input: "[~]",
// expected: "[~]\n",
// },
// {
// description: "basic - null map value",
// skipDoc: true,
// input: "a: null",
// expected: "a: null\n",
// },
}
func testYamlScenario(t *testing.T, s formatScenario) {
// switch s.scenarioType {
// case "decode":
test.AssertResultWithContext(t, s.expected, mustProcessFormatScenario(s, NewYamlDecoder(ConfiguredYamlPreferences), NewYamlEncoder(2, false, ConfiguredYamlPreferences)), s.description)
// default:
// panic(fmt.Sprintf("unhandled scenario type %q", s.scenarioType))
// }
}
func TestYamlScenarios(t *testing.T) {
for _, tt := range yamlScenarios {
testYamlScenario(t, tt)
}
// genericScenarios := make([]interface{}, len(yamlScenarios))
// for i, s := range yamlScenarios {
// genericScenarios[i] = s
// }
// documentScenarios(t, "usage", "convert", genericScenarios, documentJSONScenario)
}