This commit is contained in:
Mike Farah 2023-04-09 11:14:51 +10:00
parent 4696d11bbc
commit 4c6c653d25
22 changed files with 223 additions and 292 deletions

View File

@ -191,10 +191,11 @@ func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *
}
}
func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string, value string) *CandidateNode {
replacement := n.CreateReplacement(kind, tag, value)
func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string, style Style) *CandidateNode {
replacement := n.CreateReplacement(kind, tag, "")
replacement.LeadingContent = n.LeadingContent
replacement.TrailingContent = n.TrailingContent
replacement.Style = style
return replacement
}

View File

@ -5,8 +5,6 @@ import (
"strconv"
"strings"
"time"
yaml "gopkg.in/yaml.v3"
)
func createAddOp(lhs *ExpressionNode, rhs *ExpressionNode) *ExpressionNode {
@ -19,23 +17,20 @@ func addAssignOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
return compoundAssignFunction(d, context, expressionNode, createAddOp)
}
func toNodes(candidate *CandidateNode, lhs *CandidateNode) ([]*yaml.Node, error) {
if candidate.Node.Tag == "!!null" {
return []*yaml.Node{}, nil
}
clone, err := candidate.Copy()
if err != nil {
return nil, err
func toNodes(candidate *CandidateNode, lhs *CandidateNode) ([]*CandidateNode, error) {
if candidate.Tag == "!!null" {
return []*CandidateNode{}, nil
}
clone := candidate.Copy()
switch candidate.Node.Kind {
case yaml.SequenceNode:
return clone.Node.Content, nil
switch candidate.Kind {
case SequenceNode:
return clone.Content, nil
default:
if len(lhs.Node.Content) > 0 {
clone.Node.Style = lhs.Node.Content[0].Style
if len(lhs.Content) > 0 {
clone.Style = lhs.Content[0].Style
}
return []*yaml.Node{clone.Node}, nil
return []*CandidateNode{clone}, nil
}
}
@ -47,50 +42,50 @@ func addOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
}
func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
lhs = lhs.unwrapDocument()
rhs = rhs.unwrapDocument()
lhsNode := lhs.Node
lhsNode := lhs
if lhsNode.Tag == "!!null" {
return lhs.CreateReplacement(rhs.Node), nil
return lhs.CreateReplacement(rhs), nil
}
target := lhs.CreateReplacement(&yaml.Node{
Anchor: lhs.Node.Anchor,
target := lhs.CreateReplacement(&yaml{
Anchor: lhs.Anchor,
})
switch lhsNode.Kind {
case yaml.MappingNode:
if rhs.Node.Kind != yaml.MappingNode {
return nil, fmt.Errorf("%v (%v) cannot be added to a %v (%v)", rhs.Node.Tag, rhs.GetNicePath(), lhsNode.Tag, lhs.GetNicePath())
case MappingNode:
if rhs.Kind != MappingNode {
return nil, fmt.Errorf("%v (%v) cannot be added to a %v (%v)", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag, lhs.GetNicePath())
}
addMaps(target, lhs, rhs)
case yaml.SequenceNode:
case SequenceNode:
if err := addSequences(target, lhs, rhs); err != nil {
return nil, err
}
case yaml.ScalarNode:
if rhs.Node.Kind != yaml.ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be added to a %v (%v)", rhs.Node.Tag, rhs.GetNicePath(), lhsNode.Tag, lhs.GetNicePath())
case ScalarNode:
if rhs.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be added to a %v (%v)", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag, lhs.GetNicePath())
}
target.Node.Kind = yaml.ScalarNode
target.Node.Style = lhsNode.Style
if err := addScalars(context, target, lhsNode, rhs.Node); err != nil {
target.Kind = ScalarNode
target.Style = lhsNode.Style
if err := addScalars(context, target, lhsNode, rhs); err != nil {
return nil, err
}
}
return target, nil
}
func addScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) error {
func addScalars(context Context, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
lhsTag := lhs.Tag
rhsTag := guessTagFromCustomType(rhs)
rhsTag := rhs.guessTagFromCustomType()
lhsIsCustom := false
if !strings.HasPrefix(lhsTag, "!!") {
// custom tag - we have to have a guess
lhsTag = guessTagFromCustomType(lhs)
lhsTag = lhs.guessTagFromCustomType()
lhsIsCustom = true
}
@ -106,11 +101,11 @@ func addScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs *yam
return addDateTimes(context.GetDateTimeLayout(), target, lhs, rhs)
} else if lhsTag == "!!str" {
target.Node.Tag = lhs.Tag
target.Node.Value = lhs.Value + rhs.Value
target.Tag = lhs.Tag
target.Value = lhs.Value + rhs.Value
} else if rhsTag == "!!str" {
target.Node.Tag = rhs.Tag
target.Node.Value = lhs.Value + rhs.Value
target.Tag = rhs.Tag
target.Value = lhs.Value + rhs.Value
} else if lhsTag == "!!int" && rhsTag == "!!int" {
format, lhsNum, err := parseInt64(lhs.Value)
if err != nil {
@ -121,8 +116,8 @@ func addScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs *yam
return err
}
sum := lhsNum + rhsNum
target.Node.Tag = lhs.Tag
target.Node.Value = fmt.Sprintf(format, sum)
target.Tag = lhs.Tag
target.Value = fmt.Sprintf(format, sum)
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil {
@ -134,18 +129,18 @@ func addScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs *yam
}
sum := lhsNum + rhsNum
if lhsIsCustom {
target.Node.Tag = lhs.Tag
target.Tag = lhs.Tag
} else {
target.Node.Tag = "!!float"
target.Tag = "!!float"
}
target.Node.Value = fmt.Sprintf("%v", sum)
target.Value = fmt.Sprintf("%v", sum)
} else {
return fmt.Errorf("%v cannot be added to %v", lhsTag, rhsTag)
}
return nil
}
func addDateTimes(layout string, target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) error {
func addDateTimes(layout string, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
duration, err := time.ParseDuration(rhs.Value)
if err != nil {
@ -158,52 +153,52 @@ func addDateTimes(layout string, target *CandidateNode, lhs *yaml.Node, rhs *yam
}
newTime := currentTime.Add(duration)
target.Node.Value = newTime.Format(layout)
target.Value = newTime.Format(layout)
return nil
}
func addSequences(target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
target.Node.Kind = yaml.SequenceNode
if len(lhs.Node.Content) > 0 {
target.Node.Style = lhs.Node.Style
target.Kind = SequenceNode
if len(lhs.Content) > 0 {
target.Style = lhs.Style
}
target.Node.Tag = lhs.Node.Tag
target.Tag = lhs.Tag
extraNodes, err := toNodes(rhs, lhs)
if err != nil {
return err
}
target.Node.Content = append(deepCloneContent(lhs.Node.Content), extraNodes...)
target.Content = append(lhs.CopyChildren(), extraNodes...)
return nil
}
func addMaps(target *CandidateNode, lhsC *CandidateNode, rhsC *CandidateNode) {
lhs := lhsC.Node
rhs := rhsC.Node
lhs := lhsC
rhs := rhsC
target.Node.Content = make([]*yaml.Node, len(lhs.Content))
copy(target.Node.Content, lhs.Content)
target.Content = make([]*CandidateNode, len(lhs.Content))
copy(target.Content, lhs.Content)
for index := 0; index < len(rhs.Content); index = index + 2 {
key := rhs.Content[index]
value := rhs.Content[index+1]
log.Debug("finding %v", key.Value)
indexInLHS := findKeyInMap(target.Node, key)
indexInLHS := findKeyInMap(target, key)
log.Debug("indexInLhs %v", indexInLHS)
if indexInLHS < 0 {
// not in there, append it
target.Node.Content = append(target.Node.Content, key, value)
target.Content = append(target.Content, key, value)
} else {
// it's there, replace it
target.Node.Content[indexInLHS+1] = value
target.Content[indexInLHS+1] = value
}
}
target.Node.Kind = yaml.MappingNode
target.Kind = MappingNode
if len(lhs.Content) > 0 {
target.Node.Style = lhs.Style
target.Style = lhs.Style
}
target.Node.Tag = lhs.Tag
target.Tag = lhs.Tag
}

View File

@ -9,7 +9,7 @@ func alternativeOperator(d *dataTreeNavigator, context Context, expressionNode *
if lhs == nil {
return nil, nil
}
truthy, err := isTruthy(lhs)
truthy, err := isTruthyNode(lhs)
if err != nil {
return nil, err
}
@ -29,12 +29,8 @@ func alternativeFunc(d *dataTreeNavigator, context Context, lhs *CandidateNode,
if rhs == nil {
return lhs, nil
}
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
log.Debugf("Alternative LHS: %v", lhs.Node.Tag)
log.Debugf("- RHS: %v", rhs.Node.Tag)
isTrue, err := isTruthy(lhs)
isTrue, err := isTruthyNode(lhs)
if err != nil {
return nil, err
} else if isTrue {

View File

@ -8,9 +8,8 @@ type assignPreferences struct {
func assignUpdateFunc(prefs assignPreferences) crossFunctionCalculation {
return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
rhs.Node = unwrapDoc(rhs.Node)
if !prefs.OnlyWriteNull || lhs.Node.Tag == "!!null" {
lhs.UpdateFrom(rhs, prefs)
if !prefs.OnlyWriteNull || lhs.Tag == "!!null" {
lhs.UpdateFrom(rhs.unwrapDocument(), prefs)
}
return lhs, nil
}
@ -60,8 +59,7 @@ func assignUpdateOperator(d *dataTreeNavigator, context Context, expressionNode
if first != nil {
rhsCandidate := first.Value.(*CandidateNode)
rhsCandidate.Node = unwrapDoc(rhsCandidate.Node)
candidate.UpdateFrom(rhsCandidate, prefs)
candidate.UpdateFrom(rhsCandidate.unwrapDocument(), prefs)
}
}
@ -92,7 +90,7 @@ func assignAttributesOperator(d *dataTreeNavigator, context Context, expressionN
if expressionNode.Operation.Preferences != nil {
prefs = expressionNode.Operation.Preferences.(assignPreferences)
}
if !prefs.OnlyWriteNull || candidate.Node.Tag == "!!null" {
if !prefs.OnlyWriteNull || candidate.Tag == "!!null" {
candidate.UpdateAttributesFrom(first.Value.(*CandidateNode), prefs)
}
}

View File

@ -3,36 +3,26 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
"strings"
)
func isTruthyNode(node *yaml.Node) (bool, error) {
value := true
func isTruthyNode(candidate *CandidateNode) (bool, error) {
if candidate == nil {
return false, nil
}
node := candidate.unwrapDocument()
if node.Tag == "!!null" {
return false, nil
}
if node.Kind == yaml.ScalarNode && node.Tag == "!!bool" {
errDecoding := node.Decode(&value)
if errDecoding != nil {
return false, errDecoding
}
if node.Kind == ScalarNode && node.Tag == "!!bool" {
// yes/y/true/on
return (strings.EqualFold(node.Value, "y") ||
strings.EqualFold(node.Value, "yes") ||
strings.EqualFold(node.Value, "on") ||
strings.EqualFold(node.Value, "true")), nil
}
return value, nil
}
func isTruthy(c *CandidateNode) (bool, error) {
node := unwrapDoc(c.Node)
return isTruthyNode(node)
}
func getBoolean(candidate *CandidateNode) (bool, error) {
if candidate != nil {
candidate.Node = unwrapDoc(candidate.Node)
return isTruthy(candidate)
}
return false, nil
return true, nil
}
func getOwner(lhs *CandidateNode, rhs *CandidateNode) *CandidateNode {
@ -48,7 +38,7 @@ func getOwner(lhs *CandidateNode, rhs *CandidateNode) *CandidateNode {
func returnRhsTruthy(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
owner := getOwner(lhs, rhs)
rhsBool, err := getBoolean(rhs)
rhsBool, err := isTruthyNode(rhs)
if err != nil {
return nil, err
}
@ -61,7 +51,7 @@ func returnLHSWhen(targetBool bool) func(lhs *CandidateNode) (*CandidateNode, er
var err error
var lhsBool bool
if lhsBool, err = getBoolean(lhs); err != nil || lhsBool != targetBool {
if lhsBool, err = isTruthyNode(lhs); err != nil || lhsBool != targetBool {
return nil, err
}
owner := &CandidateNode{}
@ -72,18 +62,17 @@ func returnLHSWhen(targetBool bool) func(lhs *CandidateNode) (*CandidateNode, er
}
}
func findBoolean(wantBool bool, d *dataTreeNavigator, context Context, expressionNode *ExpressionNode, sequenceNode *yaml.Node) (bool, error) {
func findBoolean(wantBool bool, d *dataTreeNavigator, context Context, expressionNode *ExpressionNode, sequenceNode *CandidateNode) (bool, error) {
for _, node := range sequenceNode.Content {
if expressionNode != nil {
//need to evaluate the expression against the node
candidate := &CandidateNode{Node: node}
rhs, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(candidate), expressionNode)
rhs, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(node), expressionNode)
if err != nil {
return false, err
}
if rhs.MatchingNodes.Len() > 0 {
node = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node
node = rhs.MatchingNodes.Front().Value.(*CandidateNode)
} else {
// no results found, ignore this entry
continue
@ -106,8 +95,8 @@ func allOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
if candidateNode.Kind != yaml.SequenceNode {
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != SequenceNode {
return Context{}, fmt.Errorf("any only supports arrays, was %v", candidateNode.Tag)
}
booleanResult, err := findBoolean(false, d, context, expressionNode.RHS, candidateNode)
@ -125,8 +114,8 @@ func anyOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
if candidateNode.Kind != yaml.SequenceNode {
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != SequenceNode {
return Context{}, fmt.Errorf("any only supports arrays, was %v", candidateNode.Tag)
}
booleanResult, err := findBoolean(true, d, context, expressionNode.RHS, candidateNode)
@ -164,7 +153,7 @@ func notOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
log.Debug("notOperation checking %v", candidate)
truthy, errDecoding := isTruthy(candidate)
truthy, errDecoding := isTruthyNode(candidate)
if errDecoding != nil {
return Context{}, errDecoding
}

View File

@ -2,12 +2,10 @@ package yqlib
import (
"container/list"
yaml "gopkg.in/yaml.v3"
)
func collectTogether(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (*CandidateNode, error) {
collectedNode := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
collectedNode := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
collectExpResults, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(candidate), expressionNode)
@ -17,10 +15,10 @@ func collectTogether(d *dataTreeNavigator, context Context, expressionNode *Expr
for result := collectExpResults.MatchingNodes.Front(); result != nil; result = result.Next() {
resultC := result.Value.(*CandidateNode)
log.Debugf("found this: %v", NodeToString(resultC))
collectedNode.Content = append(collectedNode.Content, unwrapDoc(resultC.Node))
collectedNode.Content = append(collectedNode.Content, resultC.unwrapDocument())
}
}
return &CandidateNode{Node: collectedNode}, nil
return collectedNode, nil
}
func collectOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -28,9 +26,8 @@ func collectOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
if context.MatchingNodes.Len() == 0 {
log.Debugf("nothing to collect")
node := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq", Value: "[]"}
candidate := &CandidateNode{Node: node}
return context.SingleChildContext(candidate), nil
node := &CandidateNode{Kind: SequenceNode, Tag: "!!seq", Value: "[]"}
return context.SingleChildContext(node), nil
}
var evaluateAllTogether = true

View File

@ -2,8 +2,6 @@ package yqlib
import (
"container/list"
yaml "gopkg.in/yaml.v3"
)
/*
@ -23,26 +21,26 @@ func collectObjectOperator(d *dataTreeNavigator, originalContext Context, expres
context := originalContext.WritableClone()
if context.MatchingNodes.Len() == 0 {
node := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map", Value: "{}"}
candidate := &CandidateNode{Node: node}
candidate := &CandidateNode{Kind: MappingNode, Tag: "!!map", Value: "{}"}
return context.SingleChildContext(candidate), nil
}
first := context.MatchingNodes.Front().Value.(*CandidateNode)
var rotated = make([]*list.List, len(first.Node.Content))
var rotated = make([]*list.List, len(first.Content))
for i := 0; i < len(first.Node.Content); i++ {
for i := 0; i < len(first.Content); i++ {
rotated[i] = list.New()
}
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidateNode := el.Value.(*CandidateNode)
for i := 0; i < len(first.Node.Content); i++ {
rotated[i].PushBack(candidateNode.CreateChildInArray(i, candidateNode.Node.Content[i]))
for i := 0; i < len(first.Content); i++ {
rotated[i].PushBack(candidateNode.CreateChildInArray(i, candidateNode.Content[i]))
}
}
newObject := list.New()
for i := 0; i < len(first.Node.Content); i++ {
for i := 0; i < len(first.Content); i++ {
additions, err := collect(d, context.ChildContext(list.New()), rotated[i])
if err != nil {
return Context{}, err
@ -82,10 +80,7 @@ func collect(d *dataTreeNavigator, context Context, remainingMatches *list.List)
aggCandidate := el.Value.(*CandidateNode)
for splatEl := splatted.MatchingNodes.Front(); splatEl != nil; splatEl = splatEl.Next() {
splatCandidate := splatEl.Value.(*CandidateNode)
newCandidate, err := aggCandidate.Copy()
if err != nil {
return Context{}, err
}
newCandidate := aggCandidate.Copy()
newCandidate.Path = nil

View File

@ -3,8 +3,6 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -17,12 +15,12 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
for el := nodesToDelete.MatchingNodes.Back(); el != nil; el = el.Prev() {
candidate := el.Value.(*CandidateNode)
if candidate.Node.Kind == yaml.DocumentNode {
if candidate.Kind == DocumentNode {
//need to delete this node from context.
newResults := list.New()
for item := context.MatchingNodes.Front(); item != nil; item = item.Next() {
nodeInContext := item.Value.(*CandidateNode)
if nodeInContext.Node != candidate.Node {
if nodeInContext != candidate {
newResults.PushBack(nodeInContext)
} else {
log.Info("Need to delete this %v", NodeToString(nodeInContext))
@ -36,12 +34,12 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
return context, nil
}
parentNode := candidate.Parent.Node
parentNode := candidate.Parent
childPath := candidate.Path[len(candidate.Path)-1]
if parentNode.Kind == yaml.MappingNode {
if parentNode.Kind == MappingNode {
deleteFromMap(candidate.Parent, childPath)
} else if parentNode.Kind == yaml.SequenceNode {
} else if parentNode.Kind == SequenceNode {
deleteFromArray(candidate.Parent, childPath)
} else {
return Context{}, fmt.Errorf("Cannot delete nodes from parent of tag %v", parentNode.Tag)
@ -52,19 +50,17 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
log.Debug("deleteFromMap")
node := unwrapDoc(candidate.Node)
node := candidate.unwrapDocument()
contents := node.Content
newContents := make([]*yaml.Node, 0)
newContents := make([]*CandidateNode, 0)
for index := 0; index < len(contents); index = index + 2 {
key := contents[index]
value := contents[index+1]
childCandidate := candidate.CreateChildInMap(key, value)
shouldDelete := key.Value == childPath
log.Debugf("shouldDelete %v ? %v", childCandidate.GetKey(), shouldDelete)
log.Debugf("shouldDelete %v ? %v", value.GetKey(), shouldDelete)
if !shouldDelete {
newContents = append(newContents, key, value)
@ -75,9 +71,9 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
func deleteFromArray(candidate *CandidateNode, childPath interface{}) {
log.Debug("deleteFromArray")
node := unwrapDoc(candidate.Node)
node := candidate.unwrapDocument()
contents := node.Content
newContents := make([]*yaml.Node, 0)
newContents := make([]*CandidateNode, 0)
for index := 0; index < len(contents); index = index + 1 {
value := contents[index]

View File

@ -3,8 +3,6 @@ package yqlib
import (
"container/list"
"fmt"
"gopkg.in/yaml.v3"
)
func getDocumentIndexOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -12,8 +10,7 @@ func getDocumentIndexOperator(d *dataTreeNavigator, context Context, expressionN
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", candidate.Document), Tag: "!!int"}
scalar := candidate.CreateReplacement(node)
scalar := candidate.CreateReplacement(ScalarNode, "!!int", fmt.Sprintf("%v", candidate.Document))
results.PushBack(scalar)
}
return context.ChildContext(results), nil

View File

@ -7,8 +7,6 @@ import (
"errors"
"regexp"
"strings"
"gopkg.in/yaml.v3"
)
func configureEncoder(format PrinterOutputFormat, indent int) Encoder {
@ -78,7 +76,7 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
if originalList != nil && originalList.Len() > 0 && hasOnlyOneNewLine.MatchString(stringValue) {
original := originalList.Front().Value.(*CandidateNode)
originalNode := unwrapDoc(original.Node)
originalNode := original.unwrapDocument()
// original block did not have a newline at the end, get rid of this one too
if !endWithNewLine.MatchString(originalNode.Value) {
stringValue = chomper.ReplaceAllString(stringValue, "")
@ -92,8 +90,7 @@ func encodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
stringValue = chomper.ReplaceAllString(stringValue, "")
}
stringContentNode := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: stringValue}
results.PushBack(candidate.CreateReplacement(stringContentNode))
results.PushBack(candidate.CreateReplacement(ScalarNode, "!!str", stringValue))
}
return context.ChildContext(results), nil
}
@ -141,9 +138,9 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
context.SetVariable("decoded: "+candidate.GetKey(), candidate.AsList())
log.Debugf("got: [%v]", candidate.Node.Value)
log.Debugf("got: [%v]", candidate.Value)
err := decoder.Init(strings.NewReader(unwrapDoc(candidate.Node).Value))
err := decoder.Init(strings.NewReader(candidate.unwrapDocument().Value))
if err != nil {
return Context{}, err
}
@ -153,9 +150,15 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
return Context{}, errorReading
}
//first node is a doc
node := unwrapDoc(decodedNode.Node)
node := decodedNode.unwrapDocument()
node.Path = candidate.Path
node.Key = candidate.Key
node.Parent = candidate.Parent
node.Document = candidate.Document
node.FileIndex = candidate.FileIndex
node.Filename = candidate.Filename
results.PushBack(candidate.CreateReplacement(node))
results.PushBack(node)
}
return context.ChildContext(results), nil
}

View File

@ -3,64 +3,60 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func entrySeqFor(key *yaml.Node, value *yaml.Node) *yaml.Node {
var keyKey = &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: "key"}
var valueKey = &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: "value"}
func entrySeqFor(key *CandidateNode, value *CandidateNode) *CandidateNode {
var keyKey = &CandidateNode{Kind: ScalarNode, Tag: "!!str", Value: "key"}
var valueKey = &CandidateNode{Kind: ScalarNode, Tag: "!!str", Value: "value"}
return &yaml.Node{
Kind: yaml.MappingNode,
return &CandidateNode{
Kind: MappingNode,
Tag: "!!map",
Content: []*yaml.Node{keyKey, key, valueKey, value},
Content: []*CandidateNode{keyKey, key, valueKey, value},
}
}
func toEntriesFromMap(candidateNode *CandidateNode) *CandidateNode {
var sequence = &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
var entriesNode = candidateNode.CreateReplacementWithDocWrappers(sequence)
var sequence = candidateNode.CreateReplacementWithDocWrappers(SequenceNode, "!!seq", 0)
var contents = unwrapDoc(candidateNode.Node).Content
var contents = candidateNode.unwrapDocument().Content
for index := 0; index < len(contents); index = index + 2 {
key := contents[index]
value := contents[index+1]
sequence.Content = append(sequence.Content, entrySeqFor(key, value))
}
return entriesNode
return sequence
}
func toEntriesfromSeq(candidateNode *CandidateNode) *CandidateNode {
var sequence = &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
var entriesNode = candidateNode.CreateReplacementWithDocWrappers(sequence)
var sequence = candidateNode.CreateReplacementWithDocWrappers(SequenceNode, "!!seq", 0)
var contents = unwrapDoc(candidateNode.Node).Content
var contents = candidateNode.unwrapDocument().Content
for index := 0; index < len(contents); index = index + 1 {
key := &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!int", Value: fmt.Sprintf("%v", index)}
key := &CandidateNode{Kind: ScalarNode, Tag: "!!int", Value: fmt.Sprintf("%v", index)}
value := contents[index]
sequence.Content = append(sequence.Content, entrySeqFor(key, value))
}
return entriesNode
return sequence
}
func toEntriesOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
candidateNode := candidate.unwrapDocument()
switch candidateNode.Kind {
case yaml.MappingNode:
case MappingNode:
results.PushBack(toEntriesFromMap(candidate))
case yaml.SequenceNode:
case SequenceNode:
results.PushBack(toEntriesfromSeq(candidate))
default:
if candidateNode.Tag != "!!null" {
return Context{}, fmt.Errorf("%v has no keys", candidate.Node.Tag)
return Context{}, fmt.Errorf("%v has no keys", candidate.Tag)
}
}
}
@ -68,9 +64,8 @@ func toEntriesOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
return context.ChildContext(results), nil
}
func parseEntry(entry *yaml.Node, position int) (*yaml.Node, *yaml.Node, error) {
func parseEntry(candidateNode *CandidateNode, position int) (*CandidateNode, *CandidateNode, error) {
prefs := traversePreferences{DontAutoCreate: true}
candidateNode := &CandidateNode{Node: entry}
keyResults, err := traverseMap(Context{}, candidateNode, createStringScalarNode("key"), prefs, false)
@ -88,15 +83,14 @@ func parseEntry(entry *yaml.Node, position int) (*yaml.Node, *yaml.Node, error)
return nil, nil, fmt.Errorf("expected to find one 'value' entry but found %v in position %v", valueResults.Len(), position)
}
return keyResults.Front().Value.(*CandidateNode).Node, valueResults.Front().Value.(*CandidateNode).Node, nil
return keyResults.Front().Value.(*CandidateNode), valueResults.Front().Value.(*CandidateNode), nil
}
func fromEntries(candidateNode *CandidateNode) (*CandidateNode, error) {
var node = &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
var mapCandidateNode = candidateNode.CreateReplacementWithDocWrappers(node)
var node = candidateNode.CopyWithoutContent()
var contents = unwrapDoc(candidateNode.Node).Content
var contents = candidateNode.unwrapDocument().Content
for index := 0; index < len(contents); index = index + 1 {
key, value, err := parseEntry(contents[index], index)
@ -106,17 +100,17 @@ func fromEntries(candidateNode *CandidateNode) (*CandidateNode, error) {
node.Content = append(node.Content, key, value)
}
return mapCandidateNode, nil
return node, nil
}
func fromEntriesOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
candidateNode := candidate.unwrapDocument()
switch candidateNode.Kind {
case yaml.SequenceNode:
case SequenceNode:
mapResult, err := fromEntries(candidate)
if err != nil {
return Context{}, err

View File

@ -4,10 +4,8 @@ import (
"container/list"
"fmt"
"os"
"strings"
parse "github.com/a8m/envsubst/parse"
yaml "gopkg.in/yaml.v3"
)
type envOpPreferences struct {
@ -18,39 +16,37 @@ type envOpPreferences struct {
}
func envOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
envName := expressionNode.Operation.CandidateNode.Node.Value
envName := expressionNode.Operation.CandidateNode.Value
log.Debug("EnvOperator, env name:", envName)
rawValue := os.Getenv(envName)
preferences := expressionNode.Operation.Preferences.(envOpPreferences)
var node *yaml.Node
var node *CandidateNode
if preferences.StringValue {
node = &yaml.Node{
Kind: yaml.ScalarNode,
node = &CandidateNode{
Kind: ScalarNode,
Tag: "!!str",
Value: rawValue,
}
} else if rawValue == "" {
return Context{}, fmt.Errorf("Value for env variable '%v' not provided in env()", envName)
} else {
var dataBucket yaml.Node
decoder := yaml.NewDecoder(strings.NewReader(rawValue))
errorReading := decoder.Decode(&dataBucket)
if errorReading != nil {
return Context{}, errorReading
decoder := NewYamlDecoder(ConfiguredYamlPreferences)
result, err := decoder.Decode()
if err != nil {
return Context{}, err
}
//first node is a doc
node = unwrapDoc(&dataBucket)
node = result.unwrapDocument()
}
log.Debug("ENV tag", node.Tag)
log.Debug("ENV value", node.Value)
log.Debug("ENV Kind", node.Kind)
target := &CandidateNode{Node: node}
return context.SingleChildContext(target), nil
return context.SingleChildContext(node), nil
}
func envsubstOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -71,7 +67,7 @@ func envsubstOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := unwrapDoc(candidate.Node)
node := candidate.unwrapDocument()
if node.Tag != "!!str" {
log.Warning("EnvSubstOperator, env name:", node.Tag, node.Value)
return Context{}, fmt.Errorf("cannot substitute with %v, can only substitute strings. Hint: Most often you'll want to use '|=' over '=' for this operation", node.Tag)
@ -81,8 +77,7 @@ func envsubstOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
if err != nil {
return Context{}, err
}
targetNode := &yaml.Node{Kind: yaml.ScalarNode, Value: value, Tag: "!!str"}
result := candidate.CreateReplacement(targetNode)
result := candidate.CreateReplacement(ScalarNode, "!!str", value)
results.PushBack(result)
}

View File

@ -3,8 +3,6 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func getFilenameOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -14,8 +12,7 @@ func getFilenameOperator(d *dataTreeNavigator, context Context, expressionNode *
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := &yaml.Node{Kind: yaml.ScalarNode, Value: candidate.Filename, Tag: "!!str"}
result := candidate.CreateReplacement(node)
result := candidate.CreateReplacement(ScalarNode, "!!str", candidate.Filename)
results.PushBack(result)
}
@ -29,8 +26,7 @@ func getFileIndexOperator(d *dataTreeNavigator, context Context, expressionNode
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", candidate.FileIndex), Tag: "!!int"}
result := candidate.CreateReplacement(node)
result := candidate.CreateReplacement(ScalarNode, "!!int", fmt.Sprintf("%v", candidate.FileIndex))
results.PushBack(result)
}

View File

@ -5,8 +5,6 @@ import (
"container/list"
"fmt"
"os"
"gopkg.in/yaml.v3"
)
var LoadYamlPreferences = YamlPreferences{
@ -30,7 +28,7 @@ func loadString(filename string) (*CandidateNode, error) {
return nil, err
}
return &CandidateNode{Node: &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!str", Value: string(filebytes)}}, nil
return &CandidateNode{Kind: ScalarNode, Tag: "!!str", Value: string(filebytes)}, nil
}
func loadYaml(filename string, decoder Decoder) (*CandidateNode, error) {
@ -51,15 +49,15 @@ func loadYaml(filename string, decoder Decoder) (*CandidateNode, error) {
if documents.Len() == 0 {
// return null candidate
return &CandidateNode{Node: &yaml.Node{Kind: yaml.ScalarNode, Tag: "!!null"}}, nil
return &CandidateNode{Kind: ScalarNode, Tag: "!!null"}, nil
} else if documents.Len() == 1 {
candidate := documents.Front().Value.(*CandidateNode)
return candidate, nil
} else {
sequenceNode := &CandidateNode{Node: &yaml.Node{Kind: yaml.SequenceNode}}
sequenceNode := &CandidateNode{Kind: SequenceNode}
for doc := documents.Front(); doc != nil; doc = doc.Next() {
sequenceNode.Node.Content = append(sequenceNode.Node.Content, unwrapDoc(doc.Value.(*CandidateNode).Node))
sequenceNode.Content = append(sequenceNode.Content, doc.Value.(*CandidateNode).unwrapDocument())
}
return sequenceNode, nil
}
@ -87,7 +85,7 @@ func loadYamlOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
}
nameCandidateNode := rhs.MatchingNodes.Front().Value.(*CandidateNode)
filename := nameCandidateNode.Node.Value
filename := nameCandidateNode.Value
var contentsCandidate *CandidateNode

View File

@ -3,21 +3,19 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func createPathNodeFor(pathElement interface{}) *yaml.Node {
func createPathNodeFor(pathElement interface{}) *CandidateNode {
switch pathElement := pathElement.(type) {
case string:
return &yaml.Node{Kind: yaml.ScalarNode, Value: pathElement, Tag: "!!str"}
return &CandidateNode{Kind: ScalarNode, Value: pathElement, Tag: "!!str"}
default:
return &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", pathElement), Tag: "!!int"}
return &CandidateNode{Kind: ScalarNode, Value: fmt.Sprintf("%v", pathElement), Tag: "!!int"}
}
}
func getPathArrayFromNode(funcName string, node *yaml.Node) ([]interface{}, error) {
if node.Kind != yaml.SequenceNode {
func getPathArrayFromNode(funcName string, node *CandidateNode) ([]interface{}, error) {
if node.Kind != SequenceNode {
return nil, fmt.Errorf("%v: expected path array, but got %v instead", funcName, node.Tag)
}
@ -59,7 +57,7 @@ func setPathOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
}
lhsValue := lhsPathContext.MatchingNodes.Front().Value.(*CandidateNode)
lhsPath, err := getPathArrayFromNode("SETPATH", lhsValue.Node)
lhsPath, err := getPathArrayFromNode("SETPATH", lhsValue)
if err != nil {
return Context{}, err
@ -110,7 +108,7 @@ func delPathsOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
if pathArraysContext.MatchingNodes.Len() != 1 {
return Context{}, fmt.Errorf("DELPATHS: expected single value but found %v", pathArraysContext.MatchingNodes.Len())
}
pathArraysNode := pathArraysContext.MatchingNodes.Front().Value.(*CandidateNode).Node
pathArraysNode := pathArraysContext.MatchingNodes.Front().Value.(*CandidateNode)
if pathArraysNode.Tag != "!!seq" {
return Context{}, fmt.Errorf("DELPATHS: expected a sequence of sequences, but found %v", pathArraysNode.Tag)
@ -156,16 +154,15 @@ func getPathOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
node := candidate.CreateReplacement(SequenceNode, "!!seq", "")
content := make([]*yaml.Node, len(candidate.Path))
content := make([]*CandidateNode, len(candidate.Path))
for pathIndex := 0; pathIndex < len(candidate.Path); pathIndex++ {
path := candidate.Path[pathIndex]
content[pathIndex] = createPathNodeFor(path)
}
node.Content = content
result := candidate.CreateReplacement(node)
results.PushBack(result)
results.PushBack(node)
}
return context.ChildContext(results), nil

View File

@ -3,8 +3,6 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func reverseOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -13,19 +11,19 @@ func reverseOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != yaml.SequenceNode {
if candidateNode.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.GetNiceTag())
}
reverseList := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq", Style: candidateNode.Style}
reverseList.Content = make([]*yaml.Node, len(candidateNode.Content))
reverseList := candidate.CreateReplacementWithDocWrappers(SequenceNode, "!!tag", candidateNode.Style)
reverseList.Content = make([]*CandidateNode, len(candidateNode.Content))
for i, originalNode := range candidateNode.Content {
reverseList.Content[len(candidateNode.Content)-i-1] = originalNode
}
results.PushBack(candidate.CreateReplacementWithDocWrappers(reverseList))
results.PushBack(reverseList)
}

View File

@ -23,7 +23,7 @@ func selectOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for resultEl := rhs.MatchingNodes.Front(); resultEl != nil; resultEl = resultEl.Next() {
result := resultEl.Value.(*CandidateNode)
includeResult, errDecoding = isTruthy(result)
includeResult, errDecoding = isTruthyNode(result)
log.Debugf("isTruthy %v", includeResult)
if errDecoding != nil {
return Context{}, errDecoding

View File

@ -7,8 +7,6 @@ import (
"strconv"
"strings"
"time"
yaml "gopkg.in/yaml.v3"
)
func sortOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -26,9 +24,9 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidateNode := unwrapDoc(candidate.Node)
candidateNode := candidate.unwrapDocument()
if candidateNode.Kind != yaml.SequenceNode {
if candidateNode.Kind != SequenceNode {
return context, fmt.Errorf("node at path [%v] is not an array (it's a %v)", candidate.GetNicePath(), candidate.GetNiceTag())
}
@ -36,8 +34,7 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for i, originalNode := range candidateNode.Content {
childCandidate := candidate.CreateChildInArray(i, originalNode)
compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(childCandidate), expressionNode.RHS)
compareContext, err := d.GetMatchingNodes(context.SingleReadonlyChildContext(originalNode), expressionNode.RHS)
if err != nil {
return Context{}, err
}
@ -48,19 +45,20 @@ func sortByOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
sort.Stable(sortableArray)
sortedList := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq", Style: candidateNode.Style}
sortedList.Content = make([]*yaml.Node, len(candidateNode.Content))
sortedList := candidate.CreateReplacementWithDocWrappers(SequenceNode, "!!seq", candidateNode.Style)
sortedList.Content = make([]*CandidateNode, len(candidateNode.Content))
for i, sortedNode := range sortableArray {
sortedList.Content[i] = sortedNode.Node
}
results.PushBack(candidate.CreateReplacementWithDocWrappers(sortedList))
results.PushBack(sortedList)
}
return context.ChildContext(results), nil
}
type sortableNode struct {
Node *yaml.Node
Node *CandidateNode
CompareContext Context
dateTimeLayout string
}
@ -79,7 +77,7 @@ func (a sortableNodeArray) Less(i, j int) bool {
lhs := lhsEl.Value.(*CandidateNode)
rhs := rhsEl.Value.(*CandidateNode)
result := a.compare(lhs.Node, rhs.Node, a[i].dateTimeLayout)
result := a.compare(lhs, rhs, a[i].dateTimeLayout)
if result < 0 {
return true
@ -92,18 +90,18 @@ func (a sortableNodeArray) Less(i, j int) bool {
return false
}
func (a sortableNodeArray) compare(lhs *yaml.Node, rhs *yaml.Node, dateTimeLayout string) int {
func (a sortableNodeArray) compare(lhs *CandidateNode, rhs *CandidateNode, dateTimeLayout string) int {
lhsTag := lhs.Tag
rhsTag := rhs.Tag
if !strings.HasPrefix(lhsTag, "!!") {
// custom tag - we have to have a guess
lhsTag = guessTagFromCustomType(lhs)
lhsTag = lhs.guessTagFromCustomType()
}
if !strings.HasPrefix(rhsTag, "!!") {
// custom tag - we have to have a guess
rhsTag = guessTagFromCustomType(rhs)
rhsTag = rhs.guessTagFromCustomType()
}
isDateTime := lhsTag == "!!timestamp" && rhsTag == "!!timestamp"

View File

@ -3,23 +3,21 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func parseStyle(customStyle string) (yaml.Style, error) {
func parseStyle(customStyle string) (Style, error) {
if customStyle == "tagged" {
return yaml.TaggedStyle, nil
return TaggedStyle, nil
} else if customStyle == "double" {
return yaml.DoubleQuotedStyle, nil
return DoubleQuotedStyle, nil
} else if customStyle == "single" {
return yaml.SingleQuotedStyle, nil
return SingleQuotedStyle, nil
} else if customStyle == "literal" {
return yaml.LiteralStyle, nil
return LiteralStyle, nil
} else if customStyle == "folded" {
return yaml.FoldedStyle, nil
return FoldedStyle, nil
} else if customStyle == "flow" {
return yaml.FlowStyle, nil
return FlowStyle, nil
} else if customStyle != "" {
return 0, fmt.Errorf("Unknown style %v", customStyle)
}
@ -29,7 +27,7 @@ func parseStyle(customStyle string) (yaml.Style, error) {
func assignStyleOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("AssignStyleOperator: %v")
var style yaml.Style
var style Style
if !expressionNode.Operation.UpdateAssign {
rhs, err := d.GetMatchingNodes(context.ReadOnlyClone(), expressionNode.RHS)
if err != nil {
@ -37,7 +35,7 @@ func assignStyleOperator(d *dataTreeNavigator, context Context, expressionNode *
}
if rhs.MatchingNodes.Front() != nil {
style, err = parseStyle(rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value)
style, err = parseStyle(rhs.MatchingNodes.Front().Value.(*CandidateNode).Value)
if err != nil {
return Context{}, err
}
@ -60,14 +58,14 @@ func assignStyleOperator(d *dataTreeNavigator, context Context, expressionNode *
}
if rhs.MatchingNodes.Front() != nil {
style, err = parseStyle(rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value)
style, err = parseStyle(rhs.MatchingNodes.Front().Value.(*CandidateNode).Value)
if err != nil {
return Context{}, err
}
}
}
candidate.Node.Style = style
candidate.Style = style
}
return context, nil
@ -81,26 +79,25 @@ func getStyleOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
var style string
switch candidate.Node.Style {
case yaml.TaggedStyle:
switch candidate.Style {
case TaggedStyle:
style = "tagged"
case yaml.DoubleQuotedStyle:
case DoubleQuotedStyle:
style = "double"
case yaml.SingleQuotedStyle:
case SingleQuotedStyle:
style = "single"
case yaml.LiteralStyle:
case LiteralStyle:
style = "literal"
case yaml.FoldedStyle:
case FoldedStyle:
style = "folded"
case yaml.FlowStyle:
case FlowStyle:
style = "flow"
case 0:
style = ""
default:
style = "<unknown>"
}
node := &yaml.Node{Kind: yaml.ScalarNode, Value: style, Tag: "!!str"}
result := candidate.CreateReplacement(node)
result := candidate.CreateReplacement(ScalarNode, "!!str", style)
results.PushBack(result)
}

View File

@ -2,8 +2,6 @@ package yqlib
import (
"container/list"
yaml "gopkg.in/yaml.v3"
)
func assignTagOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -18,7 +16,7 @@ func assignTagOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
}
if rhs.MatchingNodes.Front() != nil {
tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value
tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
}
}
@ -38,10 +36,10 @@ func assignTagOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
}
if rhs.MatchingNodes.Front() != nil {
tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value
tag = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
}
}
unwrapDoc(candidate.Node).Tag = tag
candidate.unwrapDocument().Tag = tag
}
return context, nil
@ -54,8 +52,7 @@ func getTagOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
node := &yaml.Node{Kind: yaml.ScalarNode, Value: unwrapDoc(candidate.Node).Tag, Tag: "!!str"}
result := candidate.CreateReplacement(node)
result := candidate.CreateReplacement(ScalarNode, "!!str", candidate.unwrapDocument().Tag)
results.PushBack(result)
}

View File

@ -49,7 +49,7 @@ func uniqueBy(d *dataTreeNavigator, context Context, expressionNode *ExpressionN
newMatches.Set(keyValue, child)
}
}
resultNode := candidate.CreateReplacementWithDocWrappers(SequenceNode, "!!seq", "")
resultNode := candidate.CreateReplacementWithDocWrappers(SequenceNode, "!!seq", candidateNode.Style)
for el := newMatches.Front(); el != nil; el = el.Next() {
resultNode.Content = append(resultNode.Content, el.Value.(*CandidateNode))
}

View File

@ -7,22 +7,16 @@ func referenceOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
}
func valueOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debug("value = %v", expressionNode.Operation.CandidateNode.Node.Value)
log.Debug("value = %v", expressionNode.Operation.CandidateNode.Value)
if context.MatchingNodes.Len() == 0 {
clone, err := expressionNode.Operation.CandidateNode.Copy()
if err != nil {
return Context{}, err
}
clone := expressionNode.Operation.CandidateNode.Copy()
return context.SingleChildContext(clone), nil
}
var results = list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
clone, err := expressionNode.Operation.CandidateNode.Copy()
if err != nil {
return Context{}, err
}
clone := expressionNode.Operation.CandidateNode.Copy()
results.PushBack(clone)
}