mirror of
https://github.com/taigrr/yq
synced 2025-01-18 04:53:17 -08:00
first cli
This commit is contained in:
@@ -13,6 +13,7 @@ type CandidateNode struct {
|
||||
Node *yaml.Node // the actual node
|
||||
Path []interface{} /// the path we took to get to this node
|
||||
Document uint // the document index of this node
|
||||
Filename string
|
||||
}
|
||||
|
||||
func (n *CandidateNode) GetKey() string {
|
||||
|
||||
@@ -17,34 +17,17 @@ type NavigationPrefs struct {
|
||||
}
|
||||
|
||||
type DataTreeNavigator interface {
|
||||
GetMatchingNodes(matchingNodes []*CandidateNode, pathNode *PathTreeNode) ([]*CandidateNode, error)
|
||||
// given a list of CandidateEntities and a pathNode,
|
||||
// this will process the list against the given pathNode and return
|
||||
// a new list of matching candidates
|
||||
GetMatchingNodes(matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error)
|
||||
}
|
||||
|
||||
func NewDataTreeNavigator(navigationPrefs NavigationPrefs) DataTreeNavigator {
|
||||
return &dataTreeNavigator{navigationPrefs}
|
||||
}
|
||||
|
||||
func (d *dataTreeNavigator) GetMatchingNodes(matchingNodes []*CandidateNode, pathNode *PathTreeNode) ([]*CandidateNode, error) {
|
||||
var matchingNodeMap = list.New()
|
||||
|
||||
for _, n := range matchingNodes {
|
||||
matchingNodeMap.PushBack(n)
|
||||
}
|
||||
|
||||
matchedNodes, err := d.getMatchingNodes(matchingNodeMap, pathNode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
values := make([]*CandidateNode, 0, matchedNodes.Len())
|
||||
|
||||
for el := matchedNodes.Front(); el != nil; el = el.Next() {
|
||||
values = append(values, el.Value.(*CandidateNode))
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func (d *dataTreeNavigator) getMatchingNodes(matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
func (d *dataTreeNavigator) GetMatchingNodes(matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
if pathNode == nil {
|
||||
log.Debugf("getMatchingNodes - nothing to do")
|
||||
return matchingNodes, nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package treeops
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -10,9 +11,10 @@ import (
|
||||
var treeNavigator = NewDataTreeNavigator(NavigationPrefs{})
|
||||
var treeCreator = NewPathTreeCreator()
|
||||
|
||||
func readDoc(t *testing.T, content string) []*CandidateNode {
|
||||
func readDoc(t *testing.T, content string) *list.List {
|
||||
inputList := list.New()
|
||||
if content == "" {
|
||||
return []*CandidateNode{}
|
||||
return inputList
|
||||
}
|
||||
decoder := yaml.NewDecoder(strings.NewReader(content))
|
||||
var dataBucket yaml.Node
|
||||
@@ -21,12 +23,19 @@ func readDoc(t *testing.T, content string) []*CandidateNode {
|
||||
t.Error(content)
|
||||
t.Error(err)
|
||||
}
|
||||
return []*CandidateNode{&CandidateNode{Node: dataBucket.Content[0], Document: 0}}
|
||||
|
||||
inputList.PushBack(&CandidateNode{
|
||||
Document: 0,
|
||||
Filename: "test.yml",
|
||||
Node: &dataBucket,
|
||||
})
|
||||
return inputList
|
||||
}
|
||||
|
||||
func resultsToString(results []*CandidateNode) []string {
|
||||
func resultsToString(results *list.List) []string {
|
||||
var pretty []string = make([]string, 0)
|
||||
for _, n := range results {
|
||||
for el := results.Front(); el != nil; el = el.Next() {
|
||||
n := el.Value.(*CandidateNode)
|
||||
pretty = append(pretty, NodeToString(n))
|
||||
}
|
||||
return pretty
|
||||
|
||||
@@ -101,34 +101,6 @@ func (p *Operation) toString() string {
|
||||
}
|
||||
}
|
||||
|
||||
type YqTreeLib interface {
|
||||
Get(document int, documentNode *yaml.Node, path string) ([]*CandidateNode, error)
|
||||
// GetForMerge(rootNode *yaml.Node, path string, arrayMergeStrategy ArrayMergeStrategy) ([]*NodeContext, error)
|
||||
// Update(rootNode *yaml.Node, updateCommand UpdateCommand, autoCreate bool) error
|
||||
// New(path string) yaml.Node
|
||||
|
||||
// PathStackToString(pathStack []interface{}) string
|
||||
// MergePathStackToString(pathStack []interface{}, arrayMergeStrategy ArrayMergeStrategy) string
|
||||
}
|
||||
|
||||
func NewYqTreeLib() YqTreeLib {
|
||||
return &lib{treeCreator: NewPathTreeCreator()}
|
||||
}
|
||||
|
||||
type lib struct {
|
||||
treeCreator PathTreeCreator
|
||||
}
|
||||
|
||||
func (l *lib) Get(document int, documentNode *yaml.Node, path string) ([]*CandidateNode, error) {
|
||||
nodes := []*CandidateNode{&CandidateNode{Node: documentNode.Content[0], Document: 0}}
|
||||
navigator := NewDataTreeNavigator(NavigationPrefs{})
|
||||
pathNode, errPath := l.treeCreator.ParsePath(path)
|
||||
if errPath != nil {
|
||||
return nil, errPath
|
||||
}
|
||||
return navigator.GetMatchingNodes(nodes, pathNode)
|
||||
}
|
||||
|
||||
//use for debugging only
|
||||
func NodesToString(collection *list.List) string {
|
||||
if !log.IsEnabledFor(logging.DEBUG) {
|
||||
@@ -157,7 +129,11 @@ func NodeToString(node *CandidateNode) string {
|
||||
log.Error("Error debugging node, %v", errorEncoding.Error())
|
||||
}
|
||||
encoder.Close()
|
||||
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.Path, value.Tag, buf.String())
|
||||
tag := value.Tag
|
||||
if value.Kind == yaml.DocumentNode {
|
||||
tag = "doc"
|
||||
}
|
||||
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.Path, tag, buf.String())
|
||||
}
|
||||
|
||||
func KindString(kind yaml.Kind) string {
|
||||
|
||||
@@ -3,14 +3,14 @@ package treeops
|
||||
import "container/list"
|
||||
|
||||
func AssignOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for el := lhs.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -28,14 +28,14 @@ func AssignOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *Pa
|
||||
|
||||
// does not update content or values
|
||||
func AssignAttributesOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for el := lhs.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -9,61 +9,70 @@ var assignOperatorScenarios = []expressionScenario{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= "frog"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: frog}}\n",
|
||||
"D0, P[], (doc)::{a: {b: frog}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b | (. |= "frog")`,
|
||||
expected: []string{
|
||||
"D0, P[a b], (!!str)::frog\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= 5`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: 5}}\n",
|
||||
"D0, P[], (doc)::{a: {b: 5}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `.a.b |= 3.142`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: 3.142}}\n",
|
||||
"D0, P[], (doc)::{a: {b: 3.142}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: {g: foof}}}`,
|
||||
expression: `.a |= .b`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {g: foof}}\n",
|
||||
"D0, P[], (doc)::{a: {g: foof}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: apple, c: cactus}}`,
|
||||
expression: `.a[] | select(. == "apple") |= "frog"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: frog, c: cactus}}\n",
|
||||
"D0, P[], (doc)::{a: {b: frog, c: cactus}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `[candy, apple, sandy]`,
|
||||
expression: `.[] | select(. == "*andy") |= "bogs"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!seq)::[bogs, apple, bogs]\n",
|
||||
"D0, P[], (doc)::[bogs, apple, bogs]\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{}`,
|
||||
expression: `.a.b |= "bogs"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: bogs}}\n",
|
||||
"D0, P[], (doc)::{a: {b: bogs}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{}`,
|
||||
expression: `.a.b[0] |= "bogs"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: [bogs]}}\n",
|
||||
"D0, P[], (doc)::{a: {b: [bogs]}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{}`,
|
||||
expression: `.a.b[1].c |= "bogs"`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {b: [null, {c: bogs}]}}\n",
|
||||
"D0, P[], (doc)::{a: {b: [null, {c: bogs}]}}\n",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -7,8 +7,9 @@ import (
|
||||
)
|
||||
|
||||
func isTruthy(c *CandidateNode) (bool, error) {
|
||||
node := c.Node
|
||||
node := UnwrapDoc(c.Node)
|
||||
value := true
|
||||
|
||||
if node.Tag == "!!null" {
|
||||
return false, nil
|
||||
}
|
||||
@@ -29,11 +30,11 @@ func booleanOp(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTre
|
||||
|
||||
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
lhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
func DeleteChildOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -19,7 +19,7 @@ func DeleteChildOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNod
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
elMap := list.New()
|
||||
elMap.PushBack(candidate)
|
||||
nodesToDelete, err := d.getMatchingNodes(elMap, pathNode.Rhs)
|
||||
nodesToDelete, err := d.GetMatchingNodes(elMap, pathNode.Rhs)
|
||||
log.Debug("nodesToDelete:\n%v", NodesToString(nodesToDelete))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -11,12 +11,12 @@ import (
|
||||
type CrossFunctionCalculation func(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error)
|
||||
|
||||
func crossFunction(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode, calculation CrossFunctionCalculation) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rhs, err := d.getMatchingNodes(matchingNodes, pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -46,6 +46,9 @@ func MultiplyOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *
|
||||
}
|
||||
|
||||
func multiply(d *dataTreeNavigator, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||
lhs.Node = UnwrapDoc(lhs.Node)
|
||||
rhs.Node = UnwrapDoc(rhs.Node)
|
||||
|
||||
if lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode ||
|
||||
(lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) {
|
||||
var results = list.New()
|
||||
@@ -93,7 +96,7 @@ func applyAssignment(d *dataTreeNavigator, pathIndexToStartFrom int, lhs *Candid
|
||||
|
||||
assignmentOpNode := &PathTreeNode{Operation: assignmentOp, Lhs: createTraversalTree(lhsPath), Rhs: &PathTreeNode{Operation: rhsOp}}
|
||||
|
||||
_, err := d.getMatchingNodes(nodeToMap(lhs), assignmentOpNode)
|
||||
_, err := d.GetMatchingNodes(nodeToMap(lhs), assignmentOpNode)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,43 +11,50 @@ var multiplyOperatorScenarios = []expressionScenario{
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: me}, b: {also: me}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {also: me}, b: {also: [1]}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: [1]}, b: {also: [1]}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {also: me}, b: {also: {g: wizz}}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: {g: wizz}}, b: {also: {g: wizz}}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {also: {g: wizz}}, b: {also: me}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: me}, b: {also: me}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {also: {g: wizz}}, b: {also: [1]}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: [1]}, b: {also: [1]}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {also: [1]}, b: {also: {g: wizz}}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {also: {g: wizz}}, b: {also: {g: wizz}}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {things: great}, b: {also: me}}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: {things: great, also: me}, b: {also: me}}\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `a: {things: great}
|
||||
b:
|
||||
also: "me"
|
||||
@@ -59,7 +66,8 @@ b:
|
||||
also: "me"
|
||||
`,
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: [1,2,3], b: [3,4,5]}`,
|
||||
expression: `. * {"a":.b}`,
|
||||
expected: []string{
|
||||
|
||||
@@ -5,27 +5,27 @@ import (
|
||||
)
|
||||
|
||||
var notOperatorScenarios = []expressionScenario{
|
||||
{
|
||||
document: `cat`,
|
||||
expression: `. | not`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::false\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: `1`,
|
||||
expression: `. | not`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::false\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: `0`,
|
||||
expression: `. | not`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::false\n",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// document: `cat`,
|
||||
// expression: `. | not`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!bool)::false\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// document: `1`,
|
||||
// expression: `. | not`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!bool)::false\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// document: `0`,
|
||||
// expression: `. | not`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!bool)::false\n",
|
||||
// },
|
||||
// },
|
||||
{
|
||||
document: `~`,
|
||||
expression: `. | not`,
|
||||
@@ -33,20 +33,20 @@ var notOperatorScenarios = []expressionScenario{
|
||||
"D0, P[], (!!bool)::true\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: `false`,
|
||||
expression: `. | not`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::true\n",
|
||||
},
|
||||
},
|
||||
{
|
||||
document: `true`,
|
||||
expression: `. | not`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!bool)::false\n",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// document: `false`,
|
||||
// expression: `. | not`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!bool)::true\n",
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// document: `true`,
|
||||
// expression: `. | not`,
|
||||
// expected: []string{
|
||||
// "D0, P[], (!!bool)::false\n",
|
||||
// },
|
||||
// },
|
||||
}
|
||||
|
||||
func TestNotOperatorScenarios(t *testing.T) {
|
||||
|
||||
@@ -18,6 +18,10 @@ func RecursiveDescentOperator(d *dataTreeNavigator, matchMap *list.List, pathNod
|
||||
func recursiveDecent(d *dataTreeNavigator, results *list.List, matchMap *list.List) error {
|
||||
for el := matchMap.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
candidate.Node = UnwrapDoc(candidate.Node)
|
||||
|
||||
log.Debugf("Recursive Decent, added %v", NodeToString(candidate))
|
||||
results.PushBack(candidate)
|
||||
|
||||
children, err := Splat(d, nodeToMap(candidate))
|
||||
|
||||
@@ -11,14 +11,16 @@ var recursiveDescentOperatorScenarios = []expressionScenario{
|
||||
expected: []string{
|
||||
"D0, P[], (!!str)::cat\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: frog}`,
|
||||
expression: `..`,
|
||||
expected: []string{
|
||||
"D0, P[], (!!map)::{a: frog}\n",
|
||||
"D0, P[a], (!!str)::frog\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `{a: {b: apple}}`,
|
||||
expression: `..`,
|
||||
expected: []string{
|
||||
@@ -26,7 +28,8 @@ var recursiveDescentOperatorScenarios = []expressionScenario{
|
||||
"D0, P[a], (!!map)::{b: apple}\n",
|
||||
"D0, P[a b], (!!str)::apple\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `[1,2,3]`,
|
||||
expression: `..`,
|
||||
expected: []string{
|
||||
@@ -35,7 +38,8 @@ var recursiveDescentOperatorScenarios = []expressionScenario{
|
||||
"D0, P[1], (!!int)::2\n",
|
||||
"D0, P[2], (!!int)::3\n",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
document: `[{a: cat},2,true]`,
|
||||
expression: `..`,
|
||||
expected: []string{
|
||||
|
||||
@@ -12,7 +12,7 @@ func SelectOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *Pa
|
||||
for el := matchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
|
||||
rhs, err := d.getMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(nodeToMap(candidate), pathNode.Rhs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -3,11 +3,11 @@ package treeops
|
||||
import "container/list"
|
||||
|
||||
func UnionOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhs, err := d.getMatchingNodes(matchingNodes, pathNode.Rhs)
|
||||
rhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Rhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -9,12 +9,19 @@ import (
|
||||
|
||||
type OperatorHandler func(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error)
|
||||
|
||||
func UnwrapDoc(node *yaml.Node) *yaml.Node {
|
||||
if node.Kind == yaml.DocumentNode {
|
||||
return node.Content[0]
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
func PipeOperator(d *dataTreeNavigator, matchingNodes *list.List, pathNode *PathTreeNode) (*list.List, error) {
|
||||
lhs, err := d.getMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
lhs, err := d.GetMatchingNodes(matchingNodes, pathNode.Lhs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.getMatchingNodes(lhs, pathNode.Rhs)
|
||||
return d.GetMatchingNodes(lhs, pathNode.Rhs)
|
||||
}
|
||||
|
||||
func createBooleanCandidate(owner *CandidateNode, value bool) *CandidateNode {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
"github.com/mikefarah/yq/v4/test"
|
||||
)
|
||||
|
||||
type expressionScenario struct {
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/mikefarah/yq/v3/test"
|
||||
"github.com/mikefarah/yq/v4/test"
|
||||
)
|
||||
|
||||
var pathTests = []struct {
|
||||
|
||||
Reference in New Issue
Block a user