mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-13 20:15:57 +00:00
wip
This commit is contained in:
parent
54f5c9ee2f
commit
52b364ec52
@ -7,7 +7,6 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/goccy/go-json"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type jsonDecoder struct {
|
||||
@ -38,14 +37,12 @@ func (dec *jsonDecoder) Decode() (*CandidateNode, error) {
|
||||
}
|
||||
|
||||
return &CandidateNode{
|
||||
Node: &yaml.Node{
|
||||
Kind: yaml.DocumentNode,
|
||||
Content: []*yaml.Node{node},
|
||||
},
|
||||
Kind: DocumentNode,
|
||||
Content: []*CandidateNode{node},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (dec *jsonDecoder) convertToYamlNode(data *orderedMap) (*yaml.Node, error) {
|
||||
func (dec *jsonDecoder) convertToYamlNode(data *orderedMap) (*CandidateNode, error) {
|
||||
if data.kv == nil {
|
||||
switch rawData := data.altVal.(type) {
|
||||
case nil:
|
||||
@ -62,7 +59,7 @@ func (dec *jsonDecoder) convertToYamlNode(data *orderedMap) (*yaml.Node, error)
|
||||
}
|
||||
}
|
||||
|
||||
var yamlMap = &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
||||
var yamlMap = &CandidateNode{Kind: MappingNode, Tag: "!!map"}
|
||||
for _, keyValuePair := range data.kv {
|
||||
yamlValue, err := dec.convertToYamlNode(&keyValuePair.V)
|
||||
if err != nil {
|
||||
@ -74,9 +71,9 @@ func (dec *jsonDecoder) convertToYamlNode(data *orderedMap) (*yaml.Node, error)
|
||||
|
||||
}
|
||||
|
||||
func (dec *jsonDecoder) parseArray(dataArray []*orderedMap) (*yaml.Node, error) {
|
||||
func (dec *jsonDecoder) parseArray(dataArray []*orderedMap) (*CandidateNode, error) {
|
||||
|
||||
var yamlMap = &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
|
||||
var yamlMap = &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
|
||||
|
||||
for _, value := range dataArray {
|
||||
yamlValue, err := dec.convertToYamlNode(value)
|
||||
|
@ -4,8 +4,6 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/url"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type uriDecoder struct {
|
||||
@ -50,11 +48,5 @@ func (dec *uriDecoder) Decode() (*CandidateNode, error) {
|
||||
return nil, err
|
||||
}
|
||||
dec.readAnything = true
|
||||
return &CandidateNode{
|
||||
Node: &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
Tag: "!!str",
|
||||
Value: newValue,
|
||||
},
|
||||
}, nil
|
||||
return createStringScalarNode(newValue), nil
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ func (e *csvEncoder) PrintLeadingContent(writer io.Writer, content string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *csvEncoder) encodeRow(csvWriter *csv.Writer, contents []*yaml.Node) error {
|
||||
func (e *csvEncoder) encodeRow(csvWriter *csv.Writer, contents []*CandidateNode) error {
|
||||
stringValues := make([]string, len(contents))
|
||||
|
||||
for i, child := range contents {
|
||||
|
||||
if child.Kind != yaml.ScalarNode {
|
||||
if child.Kind != ScalarNode {
|
||||
return fmt.Errorf("csv encoding only works for arrays of scalars (string/numbers/booleans), child[%v] is a %v", i, child.Tag)
|
||||
}
|
||||
stringValues[i] = child.Value
|
||||
@ -41,10 +41,10 @@ func (e *csvEncoder) encodeRow(csvWriter *csv.Writer, contents []*yaml.Node) err
|
||||
return csvWriter.Write(stringValues)
|
||||
}
|
||||
|
||||
func (e *csvEncoder) encodeArrays(csvWriter *csv.Writer, content []*yaml.Node) error {
|
||||
func (e *csvEncoder) encodeArrays(csvWriter *csv.Writer, content []*CandidateNode) error {
|
||||
for i, child := range content {
|
||||
|
||||
if child.Kind != yaml.SequenceNode {
|
||||
if child.Kind != SequenceNode {
|
||||
return fmt.Errorf("csv encoding only works for arrays of scalars (string/numbers/booleans), child[%v] is a %v", i, child.Tag)
|
||||
}
|
||||
err := e.encodeRow(csvWriter, child.Content)
|
||||
@ -55,16 +55,16 @@ func (e *csvEncoder) encodeArrays(csvWriter *csv.Writer, content []*yaml.Node) e
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *csvEncoder) extractHeader(child *yaml.Node) ([]*yaml.Node, error) {
|
||||
if child.Kind != yaml.MappingNode {
|
||||
func (e *csvEncoder) extractHeader(child *CandidateNode) ([]*CandidateNode, error) {
|
||||
if child.Kind != MappingNode {
|
||||
return nil, fmt.Errorf("csv object encoding only works for arrays of flat objects (string key => string/numbers/boolean value), child[0] is a %v", child.Tag)
|
||||
}
|
||||
mapKeys := getMapKeys(child)
|
||||
return mapKeys.Content, nil
|
||||
}
|
||||
|
||||
func (e *csvEncoder) createChildRow(child *yaml.Node, headers []*yaml.Node) []*yaml.Node {
|
||||
childRow := make([]*yaml.Node, 0)
|
||||
func (e *csvEncoder) createChildRow(child *CandidateNode, headers []*CandidateNode) []*CandidateNode {
|
||||
childRow := make([]*CandidateNode, 0)
|
||||
for _, header := range headers {
|
||||
keyIndex := findKeyInMap(child, header)
|
||||
value := createScalarNode(nil, "")
|
||||
@ -77,7 +77,7 @@ func (e *csvEncoder) createChildRow(child *yaml.Node, headers []*yaml.Node) []*y
|
||||
|
||||
}
|
||||
|
||||
func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*yaml.Node) error {
|
||||
func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*CandidateNode) error {
|
||||
headers, err := e.extractHeader(content[0])
|
||||
if err != nil {
|
||||
return nil
|
||||
@ -102,7 +102,7 @@ func (e *csvEncoder) encodeObjects(csvWriter *csv.Writer, content []*yaml.Node)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *csvEncoder) Encode(writer io.Writer, originalNode *yaml.Node) error {
|
||||
func (e *csvEncoder) Encode(writer io.Writer, originalNode *CandidateNode) error {
|
||||
if originalNode.Kind == yaml.ScalarNode {
|
||||
return writeString(writer, originalNode.Value+"\n")
|
||||
}
|
||||
|
@ -94,6 +94,27 @@ var jsonScenarios = []formatScenario{
|
||||
input: `{"cat": "meow"}`,
|
||||
expected: "D0, P[], (!!map)::cat: meow\n",
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Parse json: simple: key",
|
||||
input: `{"cat": "meow"}`,
|
||||
expression: ".cat | key",
|
||||
expected: "D0, P[], (!!str)::cat\n",
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Parse json: simple: parent",
|
||||
input: `{"cat": "meow"}`,
|
||||
expression: ".cat | parent",
|
||||
expected: "D0, P[], (!!str)::cat\n",
|
||||
},
|
||||
{
|
||||
skipDoc: true,
|
||||
description: "Parse json: simple: path",
|
||||
input: `{"cat": "meow"}`,
|
||||
expression: ".cat | path",
|
||||
expected: "D0, P[], (!!str)::cat\n",
|
||||
},
|
||||
{
|
||||
description: "bad json",
|
||||
skipDoc: true,
|
||||
|
@ -202,7 +202,7 @@ func recurseNodeArrayEqual(lhs *yaml.Node, rhs *yaml.Node) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func findInArray(array *yaml.Node, item *yaml.Node) int {
|
||||
func findInArray(array *CandidateNode, item *CandidateNode) int {
|
||||
|
||||
for index := 0; index < len(array.Content); index = index + 1 {
|
||||
if recursiveNodeEqual(array.Content[index], item) {
|
||||
@ -212,7 +212,7 @@ func findInArray(array *yaml.Node, item *yaml.Node) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func findKeyInMap(dataMap *yaml.Node, item *yaml.Node) int {
|
||||
func findKeyInMap(dataMap *CandidateNode, item *CandidateNode) int {
|
||||
|
||||
for index := 0; index < len(dataMap.Content); index = index + 2 {
|
||||
if recursiveNodeEqual(dataMap.Content[index], item) {
|
||||
@ -222,7 +222,7 @@ func findKeyInMap(dataMap *yaml.Node, item *yaml.Node) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func recurseNodeObjectEqual(lhs *yaml.Node, rhs *yaml.Node) bool {
|
||||
func recurseNodeObjectEqual(lhs *CandidateNode, rhs *CandidateNode) bool {
|
||||
if len(lhs.Content) != len(rhs.Content) {
|
||||
return false
|
||||
}
|
||||
@ -253,7 +253,7 @@ func guessTagFromCustomType(node *yaml.Node) string {
|
||||
log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading)
|
||||
return node.Tag
|
||||
}
|
||||
guessedTag := unwrapDoc(dataBucket).Tag
|
||||
guessedTag := dataBucket.unwrapDocument().Tag
|
||||
log.Info("im guessing the tag %v is a %v", node.Tag, guessedTag)
|
||||
return guessedTag
|
||||
}
|
||||
@ -406,7 +406,7 @@ func createValueOperation(value interface{}, stringValue string) *Operation {
|
||||
OperationType: valueOpType,
|
||||
Value: value,
|
||||
StringValue: stringValue,
|
||||
CandidateNode: &CandidateNode{Node: node},
|
||||
CandidateNode: node,
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,13 +443,12 @@ func NodeToString(node *CandidateNode) string {
|
||||
if !log.IsEnabledFor(logging.DEBUG) {
|
||||
return ""
|
||||
}
|
||||
value := node.Node
|
||||
if value == nil {
|
||||
if node == nil {
|
||||
return "-- nil --"
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
encoder := yaml.NewEncoder(buf)
|
||||
errorEncoding := encoder.Encode(value)
|
||||
errorEncoding := encoder.Encode(node)
|
||||
if errorEncoding != nil {
|
||||
log.Error("Error debugging node, %v", errorEncoding.Error())
|
||||
}
|
||||
@ -457,10 +456,10 @@ func NodeToString(node *CandidateNode) string {
|
||||
if errorClosingEncoder != nil {
|
||||
log.Error("Error closing encoder: ", errorClosingEncoder.Error())
|
||||
}
|
||||
tag := value.Tag
|
||||
if value.Kind == yaml.DocumentNode {
|
||||
tag := node.Tag
|
||||
if node.Kind == DocumentNode {
|
||||
tag = "doc"
|
||||
} else if value.Kind == yaml.AliasNode {
|
||||
} else if node.Kind == AliasNode {
|
||||
tag = "alias"
|
||||
}
|
||||
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.Path, tag, buf.String())
|
||||
|
@ -3,8 +3,6 @@ package yqlib
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func isKeyOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
@ -30,7 +28,7 @@ func getKeyOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
if candidate.Key != nil {
|
||||
results.PushBack(candidate.CreateReplacement(candidate.Key))
|
||||
results.PushBack(candidate.Key.Copy())
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,42 +42,42 @@ func keysOperator(d *dataTreeNavigator, context Context, expressionNode *Express
|
||||
var results = list.New()
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
node := unwrapDoc(candidate.Node)
|
||||
var targetNode *yaml.Node
|
||||
if node.Kind == yaml.MappingNode {
|
||||
targetNode = getMapKeys(node)
|
||||
} else if node.Kind == yaml.SequenceNode {
|
||||
targetNode = getIndicies(node)
|
||||
candidate := el.Value.(*CandidateNode).unwrapDocument()
|
||||
|
||||
var targetNode *CandidateNode
|
||||
if candidate.Kind == MappingNode {
|
||||
targetNode = getMapKeys(candidate)
|
||||
} else if candidate.Kind == SequenceNode {
|
||||
targetNode = getIndicies(candidate)
|
||||
} else {
|
||||
return Context{}, fmt.Errorf("Cannot get keys of %v, keys only works for maps and arrays", node.Tag)
|
||||
return Context{}, fmt.Errorf("Cannot get keys of %v, keys only works for maps and arrays", candidate.Tag)
|
||||
}
|
||||
|
||||
result := candidate.CreateReplacement(targetNode)
|
||||
results.PushBack(result)
|
||||
// result := candidate.CreateReplacement(targetNode)
|
||||
results.PushBack(targetNode)
|
||||
}
|
||||
|
||||
return context.ChildContext(results), nil
|
||||
}
|
||||
|
||||
func getMapKeys(node *yaml.Node) *yaml.Node {
|
||||
contents := make([]*yaml.Node, 0)
|
||||
func getMapKeys(node *CandidateNode) *CandidateNode {
|
||||
contents := make([]*CandidateNode, 0)
|
||||
for index := 0; index < len(node.Content); index = index + 2 {
|
||||
contents = append(contents, node.Content[index])
|
||||
}
|
||||
return &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq", Content: contents}
|
||||
return &CandidateNode{Kind: SequenceNode, Tag: "!!seq", Content: contents}
|
||||
}
|
||||
|
||||
func getIndicies(node *yaml.Node) *yaml.Node {
|
||||
var contents = make([]*yaml.Node, len(node.Content))
|
||||
func getIndicies(node *CandidateNode) *CandidateNode {
|
||||
var contents = make([]*CandidateNode, len(node.Content))
|
||||
|
||||
for index := range node.Content {
|
||||
contents[index] = &yaml.Node{
|
||||
Kind: yaml.ScalarNode,
|
||||
contents[index] = &CandidateNode{
|
||||
Kind: ScalarNode,
|
||||
Tag: "!!int",
|
||||
Value: fmt.Sprintf("%v", index),
|
||||
}
|
||||
}
|
||||
|
||||
return &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq", Content: contents}
|
||||
return &CandidateNode{Kind: SequenceNode, Tag: "!!seq", Content: contents}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user