This commit is contained in:
Mike Farah 2023-04-11 12:39:22 +10:00
parent b74edd43da
commit b4cdcfb32e
18 changed files with 186 additions and 227 deletions

View File

@ -94,13 +94,17 @@ type CandidateNode struct {
IsMapKey bool
}
// func (n *CandidateNode) GetKey() string {
// keyPrefix := ""
// if n.IsMapKey {
// keyPrefix = "key-"
// }
// return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, n.Path)
// }
func (n *CandidateNode) GetKey() string {
keyPrefix := ""
if n.IsMapKey {
keyPrefix = "key-"
}
key := ""
if n.Key != nil {
key = n.Key.Value
}
return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, key)
}
func (n *CandidateNode) unwrapDocument() *CandidateNode {
if n.Kind == DocumentNode {
@ -196,29 +200,25 @@ func (n *CandidateNode) guessTagFromCustomType() string {
// }
// }
// func (n *CandidateNode) CreateChildInArray(index int) *CandidateNode {
// return &CandidateNode{
// Path: n.createChildPath(index),
// Parent: n,
// Key: createIntegerScalarNode(index),
// Document: n.Document,
// Filename: n.Filename,
// FileIndex: n.FileIndex,
// }
// }
func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *CandidateNode {
return &CandidateNode{
Parent: n.Parent,
Key: n.Key,
IsMapKey: n.IsMapKey,
Document: n.Document,
Filename: n.Filename,
FileIndex: n.FileIndex,
Kind: kind,
Tag: tag,
Value: value,
node := &CandidateNode{
Kind: kind,
Tag: tag,
Value: value,
}
n.CopyAsReplacement(node)
return node
}
func (n *CandidateNode) CopyAsReplacement(replacement *CandidateNode) *CandidateNode {
copy := replacement.Copy()
copy.Parent = n.Parent
copy.Key = n.Key
copy.IsMapKey = n.IsMapKey
copy.Document = n.Document
copy.Filename = n.Filename
copy.FileIndex = n.FileIndex
return copy
}
func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string, style Style) *CandidateNode {

View File

@ -462,7 +462,7 @@ func NodeToString(node *CandidateNode) string {
} else if node.Kind == AliasNode {
tag = "alias"
}
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.Path, tag, buf.String())
return fmt.Sprintf(`D%v, P%v, (%v)::%v`, node.Document, node.GetNicePath(), tag, buf.String())
}
func KindString(kind yaml.Kind) string {

View File

@ -48,10 +48,10 @@ func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *Candida
lhsNode := lhs
if lhsNode.Tag == "!!null" {
return lhs.CreateReplacement(rhs), nil
return lhs.CopyAsReplacement(rhs), nil
}
target := lhs.CreateReplacement(&yaml{
target := lhs.CopyAsReplacement(&CandidateNode{
Anchor: lhs.Anchor,
})

View File

@ -35,7 +35,7 @@ func collectObjectOperator(d *dataTreeNavigator, originalContext Context, expres
candidateNode := el.Value.(*CandidateNode)
for i := 0; i < len(first.Content); i++ {
rotated[i].PushBack(candidateNode.CreateChildInArray(i, candidateNode.Content[i]))
rotated[i].PushBack(candidateNode.Content[i])
}
}
@ -62,10 +62,6 @@ func collect(d *dataTreeNavigator, context Context, remainingMatches *list.List)
splatted, err := splat(context.SingleChildContext(candidate),
traversePreferences{DontFollowAlias: true, IncludeMapKeys: false})
for splatEl := splatted.MatchingNodes.Front(); splatEl != nil; splatEl = splatEl.Next() {
splatEl.Value.(*CandidateNode).Path = nil
}
if err != nil {
return Context{}, err
}
@ -82,8 +78,6 @@ func collect(d *dataTreeNavigator, context Context, remainingMatches *list.List)
splatCandidate := splatEl.Value.(*CandidateNode)
newCandidate := aggCandidate.Copy()
newCandidate.Path = nil
newCandidate, err = multiply(multiplyPreferences{AppendArrays: false})(d, context, newCandidate, splatCandidate)
if err != nil {
return Context{}, err

View File

@ -40,9 +40,9 @@ func compare(prefs compareTypePref) func(d *dataTreeNavigator, context Context,
return nil, fmt.Errorf("arrays not yet supported for comparison")
default:
if rhsU.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhsU.Tag, rhs.Path, lhsU.Tag)
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhsU.Tag, rhs.GetNicePath(), lhsU.Tag)
}
target := lhs.CreateReplacement()
target := lhs.CopyWithoutContent()
boolV, err := compareScalars(context, prefs, lhsU, rhsU)
return createBooleanCandidate(target, boolV), err

View File

@ -3,15 +3,13 @@ package yqlib
import (
"fmt"
"strings"
yaml "gopkg.in/yaml.v3"
)
func containsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
return crossFunction(d, context.ReadOnlyClone(), expressionNode, containsWithNodes, false)
}
func containsArrayElement(array *yaml.Node, item *yaml.Node) (bool, error) {
func containsArrayElement(array *CandidateNode, item *CandidateNode) (bool, error) {
for index := 0; index < len(array.Content); index = index + 1 {
containedInArray, err := contains(array.Content[index], item)
if err != nil {
@ -24,8 +22,8 @@ func containsArrayElement(array *yaml.Node, item *yaml.Node) (bool, error) {
return false, nil
}
func containsArray(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
if rhs.Kind != yaml.SequenceNode {
func containsArray(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
if rhs.Kind != SequenceNode {
return containsArrayElement(lhs, rhs)
}
for index := 0; index < len(rhs.Content); index = index + 1 {
@ -40,8 +38,8 @@ func containsArray(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
return true, nil
}
func containsObject(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
if rhs.Kind != yaml.MappingNode {
func containsObject(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
if rhs.Kind != MappingNode {
return false, nil
}
for index := 0; index < len(rhs.Content); index = index + 2 {
@ -68,21 +66,21 @@ func containsObject(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
return true, nil
}
func containsScalars(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
func containsScalars(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
if lhs.Tag == "!!str" {
return strings.Contains(lhs.Value, rhs.Value), nil
}
return lhs.Value == rhs.Value, nil
}
func contains(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
func contains(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
switch lhs.Kind {
case yaml.MappingNode:
case MappingNode:
return containsObject(lhs, rhs)
case yaml.SequenceNode:
case SequenceNode:
return containsArray(lhs, rhs)
case yaml.ScalarNode:
if rhs.Kind != yaml.ScalarNode || lhs.Tag != rhs.Tag {
case ScalarNode:
if rhs.Kind != ScalarNode || lhs.Tag != rhs.Tag {
return false, nil
}
if lhs.Tag == "!!null" {
@ -94,15 +92,15 @@ func contains(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
return false, fmt.Errorf("%v not yet supported for contains", lhs.Tag)
}
func containsWithNodes(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
func containsWithNodes(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
if lhs.Node.Kind != rhs.Node.Kind {
return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Node.Tag, lhs.Node.Tag)
if lhs.Kind != rhs.Kind {
return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Tag, lhs.Tag)
}
result, err := contains(lhs.Node, rhs.Node)
result, err := contains(lhs, rhs)
if err != nil {
return nil, err
}

View File

@ -61,7 +61,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
shouldDelete := key.Value == childPath
log.Debugf("shouldDelete %v ? %v", value.ToDebugString(), shouldDelete)
log.Debugf("shouldDelete %v ? %v", NodeToString(value), shouldDelete)
if !shouldDelete {
newContents = append(newContents, key, value)

View File

@ -4,8 +4,6 @@ import (
"fmt"
"strconv"
"strings"
yaml "gopkg.in/yaml.v3"
)
func divideOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -14,46 +12,44 @@ func divideOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
return crossFunction(d, context.ReadOnlyClone(), expressionNode, divide, false)
}
func divide(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
func divide(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
lhsNode := lhs.Node
if lhsNode.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhsNode.Tag, lhs.GetNicePath(), rhs.Node.Tag, rhs.GetNicePath())
if lhs.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
}
target := &yaml.Node{}
target := lhs.CopyWithoutContent()
if lhsNode.Kind == yaml.ScalarNode && rhs.Node.Kind == yaml.ScalarNode {
if err := divideScalars(target, lhsNode, rhs.Node); err != nil {
if lhs.Kind == ScalarNode && rhs.Kind == ScalarNode {
if err := divideScalars(target, lhs, rhs); err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhsNode.Tag, lhs.GetNicePath(), rhs.Node.Tag, rhs.GetNicePath())
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
}
return lhs.CreateReplacement(target), nil
return target, nil
}
func divideScalars(target *yaml.Node, lhs *yaml.Node, rhs *yaml.Node) error {
func divideScalars(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
}
if lhsTag == "!!str" && rhsTag == "!!str" {
res := split(lhs.Value, rhs.Value)
target.Kind = res.Kind
target.Tag = res.Tag
target.Content = res.Content
tKind, tTag, res := split(lhs.Value, rhs.Value)
target.Kind = tKind
target.Tag = tTag
target.Content = res
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
target.Kind = yaml.ScalarNode
target.Kind = ScalarNode
target.Style = lhs.Style
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)

View File

@ -151,7 +151,6 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
}
//first node is a doc
node := decodedNode.unwrapDocument()
node.Path = candidate.Path
node.Key = candidate.Key
node.Parent = candidate.Parent
node.Document = candidate.Document

View File

@ -1,7 +1,5 @@
package yqlib
import "gopkg.in/yaml.v3"
func equalsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
log.Debugf("-- equalsOperation")
return crossFunction(d, context, expressionNode, isEquals(false), true)
@ -16,7 +14,7 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
return createBooleanCandidate(owner, !flip), nil
} else if lhs == nil {
log.Debugf("lhs nil, but rhs is not")
rhsNode := unwrapDoc(rhs.Node)
rhsNode := rhs.unwrapDocument()
value := rhsNode.Tag == "!!null"
if flip {
value = !value
@ -24,7 +22,7 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
return createBooleanCandidate(rhs, value), nil
} else if rhs == nil {
log.Debugf("lhs not nil, but rhs is")
lhsNode := unwrapDoc(lhs.Node)
lhsNode := lhs.unwrapDocument()
value := lhsNode.Tag == "!!null"
if flip {
value = !value
@ -32,12 +30,12 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
return createBooleanCandidate(lhs, value), nil
}
lhsNode := unwrapDoc(lhs.Node)
rhsNode := unwrapDoc(rhs.Node)
lhsNode := lhs.unwrapDocument()
rhsNode := rhs.unwrapDocument()
if lhsNode.Tag == "!!null" {
value = (rhsNode.Tag == "!!null")
} else if lhsNode.Kind == yaml.ScalarNode && rhsNode.Kind == yaml.ScalarNode {
} else if lhsNode.Kind == ScalarNode && rhsNode.Kind == ScalarNode {
value = matchKey(lhsNode.Value, rhsNode.Value)
}
log.Debugf("%v == %v ? %v", NodeToString(lhs), NodeToString(rhs), value)

View File

@ -5,8 +5,6 @@ import (
"math"
"strconv"
"strings"
yaml "gopkg.in/yaml.v3"
)
func moduloOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -15,41 +13,39 @@ func moduloOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
return crossFunction(d, context.ReadOnlyClone(), expressionNode, modulo, false)
}
func modulo(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
func modulo(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
lhs := lhsW.unwrapDocument()
rhs := rhsW.unwrapDocument()
lhsNode := lhs.Node
if lhsNode.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhsNode.Tag, lhs.GetNicePath(), rhs.Node.Tag, rhs.GetNicePath())
if lhs.Tag == "!!null" {
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
}
target := &yaml.Node{}
target := lhs.CopyWithoutContent()
if lhsNode.Kind == yaml.ScalarNode && rhs.Node.Kind == yaml.ScalarNode {
if err := moduloScalars(target, lhsNode, rhs.Node); err != nil {
if lhs.Kind == ScalarNode && rhs.Kind == ScalarNode {
if err := moduloScalars(target, lhs, rhs); err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhsNode.Tag, lhs.GetNicePath(), rhs.Node.Tag, rhs.GetNicePath())
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
}
return lhs.CreateReplacement(target), nil
return target, nil
}
func moduloScalars(target *yaml.Node, lhs *yaml.Node, rhs *yaml.Node) error {
func moduloScalars(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
}
if lhsTag == "!!int" && rhsTag == "!!int" {
target.Kind = yaml.ScalarNode
target.Kind = ScalarNode
target.Style = lhs.Style
format, lhsNum, err := parseInt64(lhs.Value)
@ -68,7 +64,7 @@ func moduloScalars(target *yaml.Node, lhs *yaml.Node, rhs *yaml.Node) error {
target.Tag = lhs.Tag
target.Value = fmt.Sprintf(format, remainder)
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
target.Kind = yaml.ScalarNode
target.Kind = ScalarNode
target.Style = lhs.Style
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)

View File

@ -7,7 +7,6 @@ import (
"strings"
"github.com/jinzhu/copier"
yaml "gopkg.in/yaml.v3"
)
type multiplyPreferences struct {
@ -38,15 +37,15 @@ func multiplyOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
func getComments(lhs *CandidateNode, rhs *CandidateNode) (leadingContent string, headComment string, footComment string) {
leadingContent = rhs.LeadingContent
headComment = rhs.Node.HeadComment
footComment = rhs.Node.FootComment
if lhs.Node.HeadComment != "" || lhs.LeadingContent != "" {
headComment = lhs.Node.HeadComment
headComment = rhs.HeadComment
footComment = rhs.FootComment
if lhs.HeadComment != "" || lhs.LeadingContent != "" {
headComment = lhs.HeadComment
leadingContent = lhs.LeadingContent
}
if lhs.Node.FootComment != "" {
footComment = lhs.Node.FootComment
if lhs.FootComment != "" {
footComment = lhs.FootComment
}
return leadingContent, headComment, footComment
}
@ -55,27 +54,27 @@ func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator, contex
return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
// need to do this before unWrapping the potential document node
leadingContent, headComment, footComment := getComments(lhs, rhs)
lhs.Node = unwrapDoc(lhs.Node)
rhs.Node = unwrapDoc(rhs.Node)
log.Debugf("Multiplying LHS: %v", lhs.Node.Tag)
log.Debugf("- RHS: %v", rhs.Node.Tag)
lhs = lhs.unwrapDocument()
rhs = rhs.unwrapDocument()
log.Debugf("Multiplying LHS: %v", lhs.Tag)
log.Debugf("- RHS: %v", rhs.Tag)
if rhs.Node.Tag == "!!null" {
return lhs.Copy()
if rhs.Tag == "!!null" {
return lhs.Copy(), nil
}
if (lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode) ||
(lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.MappingNode) ||
(lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) ||
(lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.SequenceNode) {
if (lhs.Kind == MappingNode && rhs.Kind == MappingNode) ||
(lhs.Tag == "!!null" && rhs.Kind == MappingNode) ||
(lhs.Kind == SequenceNode && rhs.Kind == SequenceNode) ||
(lhs.Tag == "!!null" && rhs.Kind == SequenceNode) {
var newBlank = CandidateNode{}
err := copier.CopyWithOption(&newBlank, lhs, copier.Option{IgnoreEmpty: true, DeepCopy: true})
if err != nil {
return nil, err
}
newBlank.LeadingContent = leadingContent
newBlank.Node.HeadComment = headComment
newBlank.Node.FootComment = footComment
newBlank.HeadComment = headComment
newBlank.FootComment = footComment
return mergeObjects(d, context.WritableClone(), &newBlank, rhs, preferences)
}
@ -84,12 +83,12 @@ func multiply(preferences multiplyPreferences) func(d *dataTreeNavigator, contex
}
func multiplyScalars(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
lhsTag := lhs.Node.Tag
rhsTag := guessTagFromCustomType(rhs.Node)
lhsTag := lhs.Tag
rhsTag := rhs.guessTagFromCustomType()
lhsIsCustom := false
if !strings.HasPrefix(lhsTag, "!!") {
// custom tag - we have to have a guess
lhsTag = guessTagFromCustomType(lhs.Node)
lhsTag = lhs.guessTagFromCustomType()
lhsIsCustom = true
}
@ -98,46 +97,46 @@ func multiplyScalars(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, er
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
return multiplyFloats(lhs, rhs, lhsIsCustom)
}
return nil, fmt.Errorf("Cannot multiply %v with %v", lhs.Node.Tag, rhs.Node.Tag)
return nil, fmt.Errorf("Cannot multiply %v with %v", lhs.Tag, rhs.Tag)
}
func multiplyFloats(lhs *CandidateNode, rhs *CandidateNode, lhsIsCustom bool) (*CandidateNode, error) {
target := lhs.CreateReplacement(&yaml.Node{})
target.Node.Kind = yaml.ScalarNode
target.Node.Style = lhs.Node.Style
target := lhs.CopyWithoutContent()
target.Kind = ScalarNode
target.Style = lhs.Style
if lhsIsCustom {
target.Node.Tag = lhs.Node.Tag
target.Tag = lhs.Tag
} else {
target.Node.Tag = "!!float"
target.Tag = "!!float"
}
lhsNum, err := strconv.ParseFloat(lhs.Node.Value, 64)
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil {
return nil, err
}
rhsNum, err := strconv.ParseFloat(rhs.Node.Value, 64)
rhsNum, err := strconv.ParseFloat(rhs.Value, 64)
if err != nil {
return nil, err
}
target.Node.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
target.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
return target, nil
}
func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
target := lhs.CreateReplacement(&yaml.Node{})
target.Node.Kind = yaml.ScalarNode
target.Node.Style = lhs.Node.Style
target.Node.Tag = lhs.Node.Tag
target := lhs.CopyWithoutContent()
target.Kind = ScalarNode
target.Style = lhs.Style
target.Tag = lhs.Tag
format, lhsNum, err := parseInt64(lhs.Node.Value)
format, lhsNum, err := parseInt64(lhs.Value)
if err != nil {
return nil, err
}
_, rhsNum, err := parseInt64(rhs.Node.Value)
_, rhsNum, err := parseInt64(rhs.Value)
if err != nil {
return nil, err
}
target.Node.Value = fmt.Sprintf(format, lhsNum*rhsNum)
target.Value = fmt.Sprintf(format, lhsNum*rhsNum)
return target, nil
}
@ -156,12 +155,12 @@ func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs
var pathIndexToStartFrom int
if results.Front() != nil {
pathIndexToStartFrom = len(results.Front().Value.(*CandidateNode).Path)
pathIndexToStartFrom = len(results.Front().Value.(*CandidateNode).GetPath())
}
for el := results.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
if candidate.Node.Tag == "!!merge" {
if candidate.Tag == "!!merge" {
continue
}
@ -177,20 +176,20 @@ func applyAssignment(d *dataTreeNavigator, context Context, pathIndexToStartFrom
shouldAppendArrays := preferences.AppendArrays
log.Debugf("merge - applyAssignment lhs %v, rhs: %v", lhs.GetKey(), rhs.GetKey())
lhsPath := rhs.Path[pathIndexToStartFrom:]
lhsPath := rhs.GetPath()[pathIndexToStartFrom:]
log.Debugf("merge - lhsPath %v", lhsPath)
assignmentOp := &Operation{OperationType: assignAttributesOpType, Preferences: preferences.AssignPrefs}
if shouldAppendArrays && rhs.Node.Kind == yaml.SequenceNode {
if shouldAppendArrays && rhs.Kind == SequenceNode {
assignmentOp.OperationType = addAssignOpType
log.Debugf("merge - assignmentOp.OperationType = addAssignOpType")
} else if !preferences.DeepMergeArrays && rhs.Node.Kind == yaml.SequenceNode ||
(rhs.Node.Kind == yaml.ScalarNode || rhs.Node.Kind == yaml.AliasNode) {
} else if !preferences.DeepMergeArrays && rhs.Kind == SequenceNode ||
(rhs.Kind == ScalarNode || rhs.Kind == AliasNode) {
assignmentOp.OperationType = assignOpType
assignmentOp.UpdateAssign = false
log.Debugf("merge - rhs.Node.Kind == yaml.SequenceNode: %v", rhs.Node.Kind == yaml.SequenceNode)
log.Debugf("merge - rhs.Node.Kind == yaml.ScalarNode: %v", rhs.Node.Kind == yaml.ScalarNode)
log.Debugf("merge - rhs.Node.Kind == yaml.AliasNode: %v", rhs.Node.Kind == yaml.AliasNode)
log.Debugf("merge - rhs.Kind == SequenceNode: %v", rhs.Kind == SequenceNode)
log.Debugf("merge - rhs.Kind == ScalarNode: %v", rhs.Kind == ScalarNode)
log.Debugf("merge - rhs.Kind == AliasNode: %v", rhs.Kind == AliasNode)
log.Debugf("merge - assignmentOp.OperationType = assignOpType, no updateassign")
} else {
log.Debugf("merge - assignmentOp := &Operation{OperationType: assignAttributesOpType}")

View File

@ -2,8 +2,6 @@ package yqlib
import (
"container/list"
yaml "gopkg.in/yaml.v3"
)
type recursiveDescentPreferences struct {
@ -25,15 +23,13 @@ func recursiveDescentOperator(d *dataTreeNavigator, context Context, expressionN
func recursiveDecent(results *list.List, context Context, preferences recursiveDescentPreferences) error {
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
candidate.Node = unwrapDoc(candidate.Node)
candidate := el.Value.(*CandidateNode).unwrapDocument()
log.Debugf("Recursive Decent, added %v", NodeToString(candidate))
results.PushBack(candidate)
if candidate.Node.Kind != yaml.AliasNode && len(candidate.Node.Content) > 0 &&
(preferences.RecurseArray || candidate.Node.Kind != yaml.SequenceNode) {
if candidate.Kind != AliasNode && len(candidate.Content) > 0 &&
(preferences.RecurseArray || candidate.Kind != SequenceNode) {
children, err := splat(context.SingleChildContext(candidate), preferences.TraversePreferences)

View File

@ -3,8 +3,6 @@ package yqlib
import (
"container/list"
"fmt"
yaml "gopkg.in/yaml.v3"
)
func getSliceNumber(d *dataTreeNavigator, context Context, node *CandidateNode, expressionNode *ExpressionNode) (int, error) {
@ -15,7 +13,7 @@ func getSliceNumber(d *dataTreeNavigator, context Context, node *CandidateNode,
if result.MatchingNodes.Len() != 1 {
return 0, fmt.Errorf("expected to find 1 number, got %v instead", result.MatchingNodes.Len())
}
return parseInt(result.MatchingNodes.Front().Value.(*CandidateNode).Node.Value)
return parseInt(result.MatchingNodes.Front().Value.(*CandidateNode).Value)
}
func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
@ -27,8 +25,7 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
results := list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
lhsNode := el.Value.(*CandidateNode)
original := unwrapDoc(lhsNode.Node)
lhsNode := el.Value.(*CandidateNode).unwrapDocument()
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)
@ -37,7 +34,7 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
}
relativeFirstNumber := firstNumber
if relativeFirstNumber < 0 {
relativeFirstNumber = len(original.Content) + firstNumber
relativeFirstNumber = len(lhsNode.Content) + firstNumber
}
secondNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.RHS)
@ -47,24 +44,21 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
relativeSecondNumber := secondNumber
if relativeSecondNumber < 0 {
relativeSecondNumber = len(original.Content) + secondNumber
} else if relativeSecondNumber > len(original.Content) {
relativeSecondNumber = len(original.Content)
relativeSecondNumber = len(lhsNode.Content) + secondNumber
} else if relativeSecondNumber > len(lhsNode.Content) {
relativeSecondNumber = len(lhsNode.Content)
}
log.Debug("calculateIndicesToTraverse: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
var newResults []*yaml.Node
var newResults []*CandidateNode
for i := relativeFirstNumber; i < relativeSecondNumber; i++ {
newResults = append(newResults, original.Content[i])
newResults = append(newResults, lhsNode.Content[i])
}
slicedArrayNode := &yaml.Node{
Kind: yaml.SequenceNode,
Tag: original.Tag,
Content: newResults,
}
results.PushBack(lhsNode.CreateReplacement(slicedArrayNode))
sliceArrayNode := lhsNode.CreateReplacement(SequenceNode, lhsNode.Tag, "")
sliceArrayNode.Content = newResults
results.PushBack(sliceArrayNode)
}

View File

@ -5,8 +5,6 @@ import (
"strconv"
"strings"
"time"
"gopkg.in/yaml.v3"
)
func createSubtractOp(lhs *ExpressionNode, rhs *ExpressionNode) *ExpressionNode {
@ -26,50 +24,50 @@ func subtractOperator(d *dataTreeNavigator, context Context, expressionNode *Exp
}
func subtractArray(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
newLHSArray := make([]*yaml.Node, 0)
newLHSArray := make([]*CandidateNode, 0)
for lindex := 0; lindex < len(lhs.Node.Content); lindex = lindex + 1 {
for lindex := 0; lindex < len(lhs.Content); lindex = lindex + 1 {
shouldInclude := true
for rindex := 0; rindex < len(rhs.Node.Content) && shouldInclude; rindex = rindex + 1 {
if recursiveNodeEqual(lhs.Node.Content[lindex], rhs.Node.Content[rindex]) {
for rindex := 0; rindex < len(rhs.Content) && shouldInclude; rindex = rindex + 1 {
if recursiveNodeEqual(lhs.Content[lindex], rhs.Content[rindex]) {
shouldInclude = false
}
}
if shouldInclude {
newLHSArray = append(newLHSArray, lhs.Node.Content[lindex])
newLHSArray = append(newLHSArray, lhs.Content[lindex])
}
}
lhs.Node.Content = newLHSArray
lhs.Content = newLHSArray
return lhs, nil
}
func subtract(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.CopyAsReplacement(rhs), nil
}
target := lhs.CreateReplacement(&yaml.Node{})
target := lhs.CopyWithoutContent()
switch lhsNode.Kind {
case yaml.MappingNode:
case MappingNode:
return nil, fmt.Errorf("maps not yet supported for subtraction")
case yaml.SequenceNode:
if rhs.Node.Kind != yaml.SequenceNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
case SequenceNode:
if rhs.Kind != SequenceNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag)
}
return subtractArray(lhs, rhs)
case yaml.ScalarNode:
if rhs.Node.Kind != yaml.ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
case ScalarNode:
if rhs.Kind != ScalarNode {
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag)
}
target.Node.Kind = yaml.ScalarNode
target.Node.Style = lhsNode.Style
if err := subtractScalars(context, target, lhsNode, rhs.Node); err != nil {
target.Kind = ScalarNode
target.Style = lhsNode.Style
if err := subtractScalars(context, target, lhsNode, rhs); err != nil {
return nil, err
}
}
@ -77,19 +75,19 @@ func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *Ca
return target, nil
}
func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) error {
func subtractScalars(context Context, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
lhsTag := lhs.Tag
rhsTag := rhs.Tag
lhsIsCustom := false
if !strings.HasPrefix(lhsTag, "!!") {
// custom tag - we have to have a guess
lhsTag = guessTagFromCustomType(lhs)
lhsTag = lhs.guessTagFromCustomType()
lhsIsCustom = true
}
if !strings.HasPrefix(rhsTag, "!!") {
// custom tag - we have to have a guess
rhsTag = guessTagFromCustomType(rhs)
rhsTag = rhs.guessTagFromCustomType()
}
isDateTime := lhsTag == "!!timestamp"
@ -113,8 +111,8 @@ func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs
return err
}
result := lhsNum - rhsNum
target.Node.Tag = lhs.Tag
target.Node.Value = fmt.Sprintf(format, result)
target.Tag = lhs.Tag
target.Value = fmt.Sprintf(format, result)
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
if err != nil {
@ -126,11 +124,11 @@ func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs
}
result := 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", result)
target.Value = fmt.Sprintf("%v", result)
} else {
return fmt.Errorf("%v cannot be added to %v", lhs.Tag, rhs.Tag)
}
@ -138,7 +136,7 @@ func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs
return nil
}
func subtractDateTime(layout string, target *CandidateNode, lhs *yaml.Node, rhs *yaml.Node) error {
func subtractDateTime(layout string, target *CandidateNode, lhs *CandidateNode, rhs *CandidateNode) error {
var durationStr string
if strings.HasPrefix(rhs.Value, "-") {
durationStr = rhs.Value[1:]
@ -157,6 +155,6 @@ func subtractDateTime(layout string, target *CandidateNode, lhs *yaml.Node, rhs
}
newTime := currentTime.Add(duration)
target.Node.Value = newTime.Format(layout)
target.Value = newTime.Format(layout)
return nil
}

View File

@ -72,10 +72,7 @@ func variableLoopSingleChild(d *dataTreeNavigator, context Context, originalExp
if prefs.IsReference {
variableValue.PushBack(el.Value)
} else {
candidateCopy, err := el.Value.(*CandidateNode).Copy()
if err != nil {
return Context{}, err
}
candidateCopy := el.Value.(*CandidateNode).Copy()
variableValue.PushBack(candidateCopy)
}
newContext := context.ChildContext(context.MatchingNodes)

View File

@ -37,10 +37,7 @@ func compoundAssignFunction(d *dataTreeNavigator, context Context, expressionNod
for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
clone, err := candidate.Copy()
if err != nil {
return Context{}, err
}
clone := candidate.Copy()
valueCopyExp := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: clone}}
valueExpression := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: candidate}}
@ -187,8 +184,7 @@ func createBooleanCandidate(owner *CandidateNode, value bool) *CandidateNode {
if !value {
valString = "false"
}
node := &yaml.Node{Kind: yaml.ScalarNode, Value: valString, Tag: "!!bool"}
return owner.CreateReplacement(node)
return owner.CreateReplacement(ScalarNode, "!!bool", valString)
}
func createTraversalTree(path []interface{}, traversePrefs traversePreferences, targetKey bool) *ExpressionNode {

View File

@ -7,8 +7,6 @@ import (
"fmt"
"io"
"regexp"
yaml "gopkg.in/yaml.v3"
)
type Printer interface {
@ -91,7 +89,7 @@ func (p *resultsPrinter) PrintedAnything() bool {
return p.printedMatches
}
func (p *resultsPrinter) printNode(node *yaml.Node, writer io.Writer) error {
func (p *resultsPrinter) printNode(node *CandidateNode, writer io.Writer) error {
p.printedMatches = p.printedMatches || (node.Tag != "!!null" &&
(node.Tag != "!!bool" || node.Value != "false"))
return p.encoder.Encode(writer, node)
@ -161,7 +159,7 @@ func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
return err
}
if err := p.printNode(mappedDoc.Node, destination); err != nil {
if err := p.printNode(mappedDoc, destination); err != nil {
return err
}