mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-30 19:25:39 +00:00
wip
This commit is contained in:
parent
b74edd43da
commit
b4cdcfb32e
@ -94,13 +94,17 @@ type CandidateNode struct {
|
|||||||
IsMapKey bool
|
IsMapKey bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (n *CandidateNode) GetKey() string {
|
func (n *CandidateNode) GetKey() string {
|
||||||
// keyPrefix := ""
|
keyPrefix := ""
|
||||||
// if n.IsMapKey {
|
if n.IsMapKey {
|
||||||
// keyPrefix = "key-"
|
keyPrefix = "key-"
|
||||||
// }
|
}
|
||||||
// return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, n.Path)
|
key := ""
|
||||||
// }
|
if n.Key != nil {
|
||||||
|
key = n.Key.Value
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, key)
|
||||||
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) unwrapDocument() *CandidateNode {
|
func (n *CandidateNode) unwrapDocument() *CandidateNode {
|
||||||
if n.Kind == DocumentNode {
|
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 {
|
func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *CandidateNode {
|
||||||
return &CandidateNode{
|
node := &CandidateNode{
|
||||||
Parent: n.Parent,
|
|
||||||
Key: n.Key,
|
|
||||||
IsMapKey: n.IsMapKey,
|
|
||||||
Document: n.Document,
|
|
||||||
Filename: n.Filename,
|
|
||||||
FileIndex: n.FileIndex,
|
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
Value: value,
|
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 {
|
func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string, style Style) *CandidateNode {
|
||||||
|
@ -462,7 +462,7 @@ func NodeToString(node *CandidateNode) string {
|
|||||||
} else if node.Kind == AliasNode {
|
} else if node.Kind == AliasNode {
|
||||||
tag = "alias"
|
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 {
|
func KindString(kind yaml.Kind) string {
|
||||||
|
@ -48,10 +48,10 @@ func add(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *Candida
|
|||||||
lhsNode := lhs
|
lhsNode := lhs
|
||||||
|
|
||||||
if lhsNode.Tag == "!!null" {
|
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,
|
Anchor: lhs.Anchor,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ func collectObjectOperator(d *dataTreeNavigator, originalContext Context, expres
|
|||||||
candidateNode := el.Value.(*CandidateNode)
|
candidateNode := el.Value.(*CandidateNode)
|
||||||
for i := 0; i < len(first.Content); i++ {
|
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),
|
splatted, err := splat(context.SingleChildContext(candidate),
|
||||||
traversePreferences{DontFollowAlias: true, IncludeMapKeys: false})
|
traversePreferences{DontFollowAlias: true, IncludeMapKeys: false})
|
||||||
|
|
||||||
for splatEl := splatted.MatchingNodes.Front(); splatEl != nil; splatEl = splatEl.Next() {
|
|
||||||
splatEl.Value.(*CandidateNode).Path = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Context{}, err
|
return Context{}, err
|
||||||
}
|
}
|
||||||
@ -82,8 +78,6 @@ func collect(d *dataTreeNavigator, context Context, remainingMatches *list.List)
|
|||||||
splatCandidate := splatEl.Value.(*CandidateNode)
|
splatCandidate := splatEl.Value.(*CandidateNode)
|
||||||
newCandidate := aggCandidate.Copy()
|
newCandidate := aggCandidate.Copy()
|
||||||
|
|
||||||
newCandidate.Path = nil
|
|
||||||
|
|
||||||
newCandidate, err = multiply(multiplyPreferences{AppendArrays: false})(d, context, newCandidate, splatCandidate)
|
newCandidate, err = multiply(multiplyPreferences{AppendArrays: false})(d, context, newCandidate, splatCandidate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Context{}, err
|
return Context{}, err
|
||||||
|
@ -40,9 +40,9 @@ func compare(prefs compareTypePref) func(d *dataTreeNavigator, context Context,
|
|||||||
return nil, fmt.Errorf("arrays not yet supported for comparison")
|
return nil, fmt.Errorf("arrays not yet supported for comparison")
|
||||||
default:
|
default:
|
||||||
if rhsU.Kind != ScalarNode {
|
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)
|
boolV, err := compareScalars(context, prefs, lhsU, rhsU)
|
||||||
|
|
||||||
return createBooleanCandidate(target, boolV), err
|
return createBooleanCandidate(target, boolV), err
|
||||||
|
@ -3,15 +3,13 @@ package yqlib
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func containsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
func containsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||||
return crossFunction(d, context.ReadOnlyClone(), expressionNode, containsWithNodes, false)
|
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 {
|
for index := 0; index < len(array.Content); index = index + 1 {
|
||||||
containedInArray, err := contains(array.Content[index], item)
|
containedInArray, err := contains(array.Content[index], item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -24,8 +22,8 @@ func containsArrayElement(array *yaml.Node, item *yaml.Node) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsArray(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
|
func containsArray(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
|
||||||
if rhs.Kind != yaml.SequenceNode {
|
if rhs.Kind != SequenceNode {
|
||||||
return containsArrayElement(lhs, rhs)
|
return containsArrayElement(lhs, rhs)
|
||||||
}
|
}
|
||||||
for index := 0; index < len(rhs.Content); index = index + 1 {
|
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
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsObject(lhs *yaml.Node, rhs *yaml.Node) (bool, error) {
|
func containsObject(lhs *CandidateNode, rhs *CandidateNode) (bool, error) {
|
||||||
if rhs.Kind != yaml.MappingNode {
|
if rhs.Kind != MappingNode {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
for index := 0; index < len(rhs.Content); index = index + 2 {
|
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
|
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" {
|
if lhs.Tag == "!!str" {
|
||||||
return strings.Contains(lhs.Value, rhs.Value), nil
|
return strings.Contains(lhs.Value, rhs.Value), nil
|
||||||
}
|
}
|
||||||
return 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 {
|
switch lhs.Kind {
|
||||||
case yaml.MappingNode:
|
case MappingNode:
|
||||||
return containsObject(lhs, rhs)
|
return containsObject(lhs, rhs)
|
||||||
case yaml.SequenceNode:
|
case SequenceNode:
|
||||||
return containsArray(lhs, rhs)
|
return containsArray(lhs, rhs)
|
||||||
case yaml.ScalarNode:
|
case ScalarNode:
|
||||||
if rhs.Kind != yaml.ScalarNode || lhs.Tag != rhs.Tag {
|
if rhs.Kind != ScalarNode || lhs.Tag != rhs.Tag {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if lhs.Tag == "!!null" {
|
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)
|
return false, fmt.Errorf("%v not yet supported for contains", lhs.Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsWithNodes(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
func containsWithNodes(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
|
||||||
lhs.Node = unwrapDoc(lhs.Node)
|
lhs := lhsW.unwrapDocument()
|
||||||
rhs.Node = unwrapDoc(rhs.Node)
|
rhs := rhsW.unwrapDocument()
|
||||||
|
|
||||||
if lhs.Node.Kind != rhs.Node.Kind {
|
if lhs.Kind != rhs.Kind {
|
||||||
return nil, fmt.Errorf("%v cannot check contained in %v", rhs.Node.Tag, lhs.Node.Tag)
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
|
|||||||
|
|
||||||
shouldDelete := key.Value == childPath
|
shouldDelete := key.Value == childPath
|
||||||
|
|
||||||
log.Debugf("shouldDelete %v ? %v", value.ToDebugString(), shouldDelete)
|
log.Debugf("shouldDelete %v ? %v", NodeToString(value), shouldDelete)
|
||||||
|
|
||||||
if !shouldDelete {
|
if !shouldDelete {
|
||||||
newContents = append(newContents, key, value)
|
newContents = append(newContents, key, value)
|
||||||
|
@ -4,8 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func divideOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
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)
|
return crossFunction(d, context.ReadOnlyClone(), expressionNode, divide, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func divide(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
func divide(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
|
||||||
lhs.Node = unwrapDoc(lhs.Node)
|
lhs := lhsW.unwrapDocument()
|
||||||
rhs.Node = unwrapDoc(rhs.Node)
|
rhs := rhsW.unwrapDocument()
|
||||||
|
|
||||||
lhsNode := lhs.Node
|
if lhs.Tag == "!!null" {
|
||||||
|
return nil, fmt.Errorf("%v (%v) cannot be divided by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
|
||||||
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())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target := &yaml.Node{}
|
target := lhs.CopyWithoutContent()
|
||||||
|
|
||||||
if lhsNode.Kind == yaml.ScalarNode && rhs.Node.Kind == yaml.ScalarNode {
|
if lhs.Kind == ScalarNode && rhs.Kind == ScalarNode {
|
||||||
if err := divideScalars(target, lhsNode, rhs.Node); err != nil {
|
if err := divideScalars(target, lhs, rhs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
lhsTag := lhs.Tag
|
||||||
rhsTag := guessTagFromCustomType(rhs)
|
rhsTag := rhs.guessTagFromCustomType()
|
||||||
lhsIsCustom := false
|
lhsIsCustom := false
|
||||||
if !strings.HasPrefix(lhsTag, "!!") {
|
if !strings.HasPrefix(lhsTag, "!!") {
|
||||||
// custom tag - we have to have a guess
|
// custom tag - we have to have a guess
|
||||||
lhsTag = guessTagFromCustomType(lhs)
|
lhsTag = lhs.guessTagFromCustomType()
|
||||||
lhsIsCustom = true
|
lhsIsCustom = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhsTag == "!!str" && rhsTag == "!!str" {
|
if lhsTag == "!!str" && rhsTag == "!!str" {
|
||||||
res := split(lhs.Value, rhs.Value)
|
tKind, tTag, res := split(lhs.Value, rhs.Value)
|
||||||
target.Kind = res.Kind
|
target.Kind = tKind
|
||||||
target.Tag = res.Tag
|
target.Tag = tTag
|
||||||
target.Content = res.Content
|
target.Content = res
|
||||||
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
||||||
target.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Style = lhs.Style
|
target.Style = lhs.Style
|
||||||
|
|
||||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||||
|
@ -151,7 +151,6 @@ func decodeOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
}
|
}
|
||||||
//first node is a doc
|
//first node is a doc
|
||||||
node := decodedNode.unwrapDocument()
|
node := decodedNode.unwrapDocument()
|
||||||
node.Path = candidate.Path
|
|
||||||
node.Key = candidate.Key
|
node.Key = candidate.Key
|
||||||
node.Parent = candidate.Parent
|
node.Parent = candidate.Parent
|
||||||
node.Document = candidate.Document
|
node.Document = candidate.Document
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package yqlib
|
package yqlib
|
||||||
|
|
||||||
import "gopkg.in/yaml.v3"
|
|
||||||
|
|
||||||
func equalsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
func equalsOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||||
log.Debugf("-- equalsOperation")
|
log.Debugf("-- equalsOperation")
|
||||||
return crossFunction(d, context, expressionNode, isEquals(false), true)
|
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
|
return createBooleanCandidate(owner, !flip), nil
|
||||||
} else if lhs == nil {
|
} else if lhs == nil {
|
||||||
log.Debugf("lhs nil, but rhs is not")
|
log.Debugf("lhs nil, but rhs is not")
|
||||||
rhsNode := unwrapDoc(rhs.Node)
|
rhsNode := rhs.unwrapDocument()
|
||||||
value := rhsNode.Tag == "!!null"
|
value := rhsNode.Tag == "!!null"
|
||||||
if flip {
|
if flip {
|
||||||
value = !value
|
value = !value
|
||||||
@ -24,7 +22,7 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
|
|||||||
return createBooleanCandidate(rhs, value), nil
|
return createBooleanCandidate(rhs, value), nil
|
||||||
} else if rhs == nil {
|
} else if rhs == nil {
|
||||||
log.Debugf("lhs not nil, but rhs is")
|
log.Debugf("lhs not nil, but rhs is")
|
||||||
lhsNode := unwrapDoc(lhs.Node)
|
lhsNode := lhs.unwrapDocument()
|
||||||
value := lhsNode.Tag == "!!null"
|
value := lhsNode.Tag == "!!null"
|
||||||
if flip {
|
if flip {
|
||||||
value = !value
|
value = !value
|
||||||
@ -32,12 +30,12 @@ func isEquals(flip bool) func(d *dataTreeNavigator, context Context, lhs *Candid
|
|||||||
return createBooleanCandidate(lhs, value), nil
|
return createBooleanCandidate(lhs, value), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
lhsNode := unwrapDoc(lhs.Node)
|
lhsNode := lhs.unwrapDocument()
|
||||||
rhsNode := unwrapDoc(rhs.Node)
|
rhsNode := rhs.unwrapDocument()
|
||||||
|
|
||||||
if lhsNode.Tag == "!!null" {
|
if lhsNode.Tag == "!!null" {
|
||||||
value = (rhsNode.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)
|
value = matchKey(lhsNode.Value, rhsNode.Value)
|
||||||
}
|
}
|
||||||
log.Debugf("%v == %v ? %v", NodeToString(lhs), NodeToString(rhs), value)
|
log.Debugf("%v == %v ? %v", NodeToString(lhs), NodeToString(rhs), value)
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func moduloOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
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)
|
return crossFunction(d, context.ReadOnlyClone(), expressionNode, modulo, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func modulo(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
func modulo(d *dataTreeNavigator, context Context, lhsW *CandidateNode, rhsW *CandidateNode) (*CandidateNode, error) {
|
||||||
lhs.Node = unwrapDoc(lhs.Node)
|
lhs := lhsW.unwrapDocument()
|
||||||
rhs.Node = unwrapDoc(rhs.Node)
|
rhs := rhsW.unwrapDocument()
|
||||||
|
|
||||||
lhsNode := lhs.Node
|
if lhs.Tag == "!!null" {
|
||||||
|
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhs.Tag, lhs.GetNicePath(), rhs.Tag, rhs.GetNicePath())
|
||||||
if lhsNode.Tag == "!!null" {
|
|
||||||
return nil, fmt.Errorf("%v (%v) cannot modulo by %v (%v)", lhsNode.Tag, lhs.GetNicePath(), rhs.Node.Tag, rhs.GetNicePath())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target := &yaml.Node{}
|
target := lhs.CopyWithoutContent()
|
||||||
|
|
||||||
if lhsNode.Kind == yaml.ScalarNode && rhs.Node.Kind == yaml.ScalarNode {
|
if lhs.Kind == ScalarNode && rhs.Kind == ScalarNode {
|
||||||
if err := moduloScalars(target, lhsNode, rhs.Node); err != nil {
|
if err := moduloScalars(target, lhs, rhs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
lhsTag := lhs.Tag
|
||||||
rhsTag := guessTagFromCustomType(rhs)
|
rhsTag := rhs.guessTagFromCustomType()
|
||||||
lhsIsCustom := false
|
lhsIsCustom := false
|
||||||
if !strings.HasPrefix(lhsTag, "!!") {
|
if !strings.HasPrefix(lhsTag, "!!") {
|
||||||
// custom tag - we have to have a guess
|
// custom tag - we have to have a guess
|
||||||
lhsTag = guessTagFromCustomType(lhs)
|
lhsTag = lhs.guessTagFromCustomType()
|
||||||
lhsIsCustom = true
|
lhsIsCustom = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhsTag == "!!int" && rhsTag == "!!int" {
|
if lhsTag == "!!int" && rhsTag == "!!int" {
|
||||||
target.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Style = lhs.Style
|
target.Style = lhs.Style
|
||||||
|
|
||||||
format, lhsNum, err := parseInt64(lhs.Value)
|
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.Tag = lhs.Tag
|
||||||
target.Value = fmt.Sprintf(format, remainder)
|
target.Value = fmt.Sprintf(format, remainder)
|
||||||
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
||||||
target.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Style = lhs.Style
|
target.Style = lhs.Style
|
||||||
|
|
||||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type multiplyPreferences struct {
|
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) {
|
func getComments(lhs *CandidateNode, rhs *CandidateNode) (leadingContent string, headComment string, footComment string) {
|
||||||
leadingContent = rhs.LeadingContent
|
leadingContent = rhs.LeadingContent
|
||||||
headComment = rhs.Node.HeadComment
|
headComment = rhs.HeadComment
|
||||||
footComment = rhs.Node.FootComment
|
footComment = rhs.FootComment
|
||||||
if lhs.Node.HeadComment != "" || lhs.LeadingContent != "" {
|
if lhs.HeadComment != "" || lhs.LeadingContent != "" {
|
||||||
headComment = lhs.Node.HeadComment
|
headComment = lhs.HeadComment
|
||||||
leadingContent = lhs.LeadingContent
|
leadingContent = lhs.LeadingContent
|
||||||
}
|
}
|
||||||
|
|
||||||
if lhs.Node.FootComment != "" {
|
if lhs.FootComment != "" {
|
||||||
footComment = lhs.Node.FootComment
|
footComment = lhs.FootComment
|
||||||
}
|
}
|
||||||
return leadingContent, headComment, 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) {
|
return func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||||
// need to do this before unWrapping the potential document node
|
// need to do this before unWrapping the potential document node
|
||||||
leadingContent, headComment, footComment := getComments(lhs, rhs)
|
leadingContent, headComment, footComment := getComments(lhs, rhs)
|
||||||
lhs.Node = unwrapDoc(lhs.Node)
|
lhs = lhs.unwrapDocument()
|
||||||
rhs.Node = unwrapDoc(rhs.Node)
|
rhs = rhs.unwrapDocument()
|
||||||
log.Debugf("Multiplying LHS: %v", lhs.Node.Tag)
|
log.Debugf("Multiplying LHS: %v", lhs.Tag)
|
||||||
log.Debugf("- RHS: %v", rhs.Node.Tag)
|
log.Debugf("- RHS: %v", rhs.Tag)
|
||||||
|
|
||||||
if rhs.Node.Tag == "!!null" {
|
if rhs.Tag == "!!null" {
|
||||||
return lhs.Copy()
|
return lhs.Copy(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lhs.Node.Kind == yaml.MappingNode && rhs.Node.Kind == yaml.MappingNode) ||
|
if (lhs.Kind == MappingNode && rhs.Kind == MappingNode) ||
|
||||||
(lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.MappingNode) ||
|
(lhs.Tag == "!!null" && rhs.Kind == MappingNode) ||
|
||||||
(lhs.Node.Kind == yaml.SequenceNode && rhs.Node.Kind == yaml.SequenceNode) ||
|
(lhs.Kind == SequenceNode && rhs.Kind == SequenceNode) ||
|
||||||
(lhs.Node.Tag == "!!null" && rhs.Node.Kind == yaml.SequenceNode) {
|
(lhs.Tag == "!!null" && rhs.Kind == SequenceNode) {
|
||||||
var newBlank = CandidateNode{}
|
var newBlank = CandidateNode{}
|
||||||
err := copier.CopyWithOption(&newBlank, lhs, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
err := copier.CopyWithOption(&newBlank, lhs, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newBlank.LeadingContent = leadingContent
|
newBlank.LeadingContent = leadingContent
|
||||||
newBlank.Node.HeadComment = headComment
|
newBlank.HeadComment = headComment
|
||||||
newBlank.Node.FootComment = footComment
|
newBlank.FootComment = footComment
|
||||||
|
|
||||||
return mergeObjects(d, context.WritableClone(), &newBlank, rhs, preferences)
|
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) {
|
func multiplyScalars(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||||
lhsTag := lhs.Node.Tag
|
lhsTag := lhs.Tag
|
||||||
rhsTag := guessTagFromCustomType(rhs.Node)
|
rhsTag := rhs.guessTagFromCustomType()
|
||||||
lhsIsCustom := false
|
lhsIsCustom := false
|
||||||
if !strings.HasPrefix(lhsTag, "!!") {
|
if !strings.HasPrefix(lhsTag, "!!") {
|
||||||
// custom tag - we have to have a guess
|
// custom tag - we have to have a guess
|
||||||
lhsTag = guessTagFromCustomType(lhs.Node)
|
lhsTag = lhs.guessTagFromCustomType()
|
||||||
lhsIsCustom = true
|
lhsIsCustom = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,46 +97,46 @@ func multiplyScalars(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, er
|
|||||||
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
||||||
return multiplyFloats(lhs, rhs, lhsIsCustom)
|
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) {
|
func multiplyFloats(lhs *CandidateNode, rhs *CandidateNode, lhsIsCustom bool) (*CandidateNode, error) {
|
||||||
target := lhs.CreateReplacement(&yaml.Node{})
|
target := lhs.CopyWithoutContent()
|
||||||
target.Node.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Node.Style = lhs.Node.Style
|
target.Style = lhs.Style
|
||||||
if lhsIsCustom {
|
if lhsIsCustom {
|
||||||
target.Node.Tag = lhs.Node.Tag
|
target.Tag = lhs.Tag
|
||||||
} else {
|
} 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rhsNum, err := strconv.ParseFloat(rhs.Node.Value, 64)
|
rhsNum, err := strconv.ParseFloat(rhs.Value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
target.Node.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
|
target.Value = fmt.Sprintf("%v", lhsNum*rhsNum)
|
||||||
return target, nil
|
return target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
func multiplyIntegers(lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||||
target := lhs.CreateReplacement(&yaml.Node{})
|
target := lhs.CopyWithoutContent()
|
||||||
target.Node.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Node.Style = lhs.Node.Style
|
target.Style = lhs.Style
|
||||||
target.Node.Tag = lhs.Node.Tag
|
target.Tag = lhs.Tag
|
||||||
|
|
||||||
format, lhsNum, err := parseInt64(lhs.Node.Value)
|
format, lhsNum, err := parseInt64(lhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
_, rhsNum, err := parseInt64(rhs.Node.Value)
|
_, rhsNum, err := parseInt64(rhs.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
target.Node.Value = fmt.Sprintf(format, lhsNum*rhsNum)
|
target.Value = fmt.Sprintf(format, lhsNum*rhsNum)
|
||||||
return target, nil
|
return target, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,12 +155,12 @@ func mergeObjects(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs
|
|||||||
|
|
||||||
var pathIndexToStartFrom int
|
var pathIndexToStartFrom int
|
||||||
if results.Front() != nil {
|
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() {
|
for el := results.Front(); el != nil; el = el.Next() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
if candidate.Node.Tag == "!!merge" {
|
if candidate.Tag == "!!merge" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,20 +176,20 @@ func applyAssignment(d *dataTreeNavigator, context Context, pathIndexToStartFrom
|
|||||||
shouldAppendArrays := preferences.AppendArrays
|
shouldAppendArrays := preferences.AppendArrays
|
||||||
log.Debugf("merge - applyAssignment lhs %v, rhs: %v", lhs.GetKey(), rhs.GetKey())
|
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)
|
log.Debugf("merge - lhsPath %v", lhsPath)
|
||||||
|
|
||||||
assignmentOp := &Operation{OperationType: assignAttributesOpType, Preferences: preferences.AssignPrefs}
|
assignmentOp := &Operation{OperationType: assignAttributesOpType, Preferences: preferences.AssignPrefs}
|
||||||
if shouldAppendArrays && rhs.Node.Kind == yaml.SequenceNode {
|
if shouldAppendArrays && rhs.Kind == SequenceNode {
|
||||||
assignmentOp.OperationType = addAssignOpType
|
assignmentOp.OperationType = addAssignOpType
|
||||||
log.Debugf("merge - assignmentOp.OperationType = addAssignOpType")
|
log.Debugf("merge - assignmentOp.OperationType = addAssignOpType")
|
||||||
} else if !preferences.DeepMergeArrays && rhs.Node.Kind == yaml.SequenceNode ||
|
} else if !preferences.DeepMergeArrays && rhs.Kind == SequenceNode ||
|
||||||
(rhs.Node.Kind == yaml.ScalarNode || rhs.Node.Kind == yaml.AliasNode) {
|
(rhs.Kind == ScalarNode || rhs.Kind == AliasNode) {
|
||||||
assignmentOp.OperationType = assignOpType
|
assignmentOp.OperationType = assignOpType
|
||||||
assignmentOp.UpdateAssign = false
|
assignmentOp.UpdateAssign = false
|
||||||
log.Debugf("merge - rhs.Node.Kind == yaml.SequenceNode: %v", rhs.Node.Kind == yaml.SequenceNode)
|
log.Debugf("merge - rhs.Kind == SequenceNode: %v", rhs.Kind == SequenceNode)
|
||||||
log.Debugf("merge - rhs.Node.Kind == yaml.ScalarNode: %v", rhs.Node.Kind == yaml.ScalarNode)
|
log.Debugf("merge - rhs.Kind == ScalarNode: %v", rhs.Kind == ScalarNode)
|
||||||
log.Debugf("merge - rhs.Node.Kind == yaml.AliasNode: %v", rhs.Node.Kind == yaml.AliasNode)
|
log.Debugf("merge - rhs.Kind == AliasNode: %v", rhs.Kind == AliasNode)
|
||||||
log.Debugf("merge - assignmentOp.OperationType = assignOpType, no updateassign")
|
log.Debugf("merge - assignmentOp.OperationType = assignOpType, no updateassign")
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("merge - assignmentOp := &Operation{OperationType: assignAttributesOpType}")
|
log.Debugf("merge - assignmentOp := &Operation{OperationType: assignAttributesOpType}")
|
||||||
|
@ -2,8 +2,6 @@ package yqlib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type recursiveDescentPreferences struct {
|
type recursiveDescentPreferences struct {
|
||||||
@ -25,15 +23,13 @@ func recursiveDescentOperator(d *dataTreeNavigator, context Context, expressionN
|
|||||||
|
|
||||||
func recursiveDecent(results *list.List, context Context, preferences recursiveDescentPreferences) error {
|
func recursiveDecent(results *list.List, context Context, preferences recursiveDescentPreferences) error {
|
||||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode).unwrapDocument()
|
||||||
|
|
||||||
candidate.Node = unwrapDoc(candidate.Node)
|
|
||||||
|
|
||||||
log.Debugf("Recursive Decent, added %v", NodeToString(candidate))
|
log.Debugf("Recursive Decent, added %v", NodeToString(candidate))
|
||||||
results.PushBack(candidate)
|
results.PushBack(candidate)
|
||||||
|
|
||||||
if candidate.Node.Kind != yaml.AliasNode && len(candidate.Node.Content) > 0 &&
|
if candidate.Kind != AliasNode && len(candidate.Content) > 0 &&
|
||||||
(preferences.RecurseArray || candidate.Node.Kind != yaml.SequenceNode) {
|
(preferences.RecurseArray || candidate.Kind != SequenceNode) {
|
||||||
|
|
||||||
children, err := splat(context.SingleChildContext(candidate), preferences.TraversePreferences)
|
children, err := splat(context.SingleChildContext(candidate), preferences.TraversePreferences)
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@ package yqlib
|
|||||||
import (
|
import (
|
||||||
"container/list"
|
"container/list"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getSliceNumber(d *dataTreeNavigator, context Context, node *CandidateNode, expressionNode *ExpressionNode) (int, error) {
|
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 {
|
if result.MatchingNodes.Len() != 1 {
|
||||||
return 0, fmt.Errorf("expected to find 1 number, got %v instead", result.MatchingNodes.Len())
|
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) {
|
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()
|
results := list.New()
|
||||||
|
|
||||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||||
lhsNode := el.Value.(*CandidateNode)
|
lhsNode := el.Value.(*CandidateNode).unwrapDocument()
|
||||||
original := unwrapDoc(lhsNode.Node)
|
|
||||||
|
|
||||||
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)
|
firstNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.LHS)
|
||||||
|
|
||||||
@ -37,7 +34,7 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
|
|||||||
}
|
}
|
||||||
relativeFirstNumber := firstNumber
|
relativeFirstNumber := firstNumber
|
||||||
if relativeFirstNumber < 0 {
|
if relativeFirstNumber < 0 {
|
||||||
relativeFirstNumber = len(original.Content) + firstNumber
|
relativeFirstNumber = len(lhsNode.Content) + firstNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
secondNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.RHS)
|
secondNumber, err := getSliceNumber(d, context, lhsNode, expressionNode.RHS)
|
||||||
@ -47,24 +44,21 @@ func sliceArrayOperator(d *dataTreeNavigator, context Context, expressionNode *E
|
|||||||
|
|
||||||
relativeSecondNumber := secondNumber
|
relativeSecondNumber := secondNumber
|
||||||
if relativeSecondNumber < 0 {
|
if relativeSecondNumber < 0 {
|
||||||
relativeSecondNumber = len(original.Content) + secondNumber
|
relativeSecondNumber = len(lhsNode.Content) + secondNumber
|
||||||
} else if relativeSecondNumber > len(original.Content) {
|
} else if relativeSecondNumber > len(lhsNode.Content) {
|
||||||
relativeSecondNumber = len(original.Content)
|
relativeSecondNumber = len(lhsNode.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("calculateIndicesToTraverse: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
|
log.Debug("calculateIndicesToTraverse: slice from %v to %v", relativeFirstNumber, relativeSecondNumber)
|
||||||
|
|
||||||
var newResults []*yaml.Node
|
var newResults []*CandidateNode
|
||||||
for i := relativeFirstNumber; i < relativeSecondNumber; i++ {
|
for i := relativeFirstNumber; i < relativeSecondNumber; i++ {
|
||||||
newResults = append(newResults, original.Content[i])
|
newResults = append(newResults, lhsNode.Content[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
slicedArrayNode := &yaml.Node{
|
sliceArrayNode := lhsNode.CreateReplacement(SequenceNode, lhsNode.Tag, "")
|
||||||
Kind: yaml.SequenceNode,
|
sliceArrayNode.Content = newResults
|
||||||
Tag: original.Tag,
|
results.PushBack(sliceArrayNode)
|
||||||
Content: newResults,
|
|
||||||
}
|
|
||||||
results.PushBack(lhsNode.CreateReplacement(slicedArrayNode))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func createSubtractOp(lhs *ExpressionNode, rhs *ExpressionNode) *ExpressionNode {
|
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) {
|
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
|
shouldInclude := true
|
||||||
for rindex := 0; rindex < len(rhs.Node.Content) && shouldInclude; rindex = rindex + 1 {
|
for rindex := 0; rindex < len(rhs.Content) && shouldInclude; rindex = rindex + 1 {
|
||||||
if recursiveNodeEqual(lhs.Node.Content[lindex], rhs.Node.Content[rindex]) {
|
if recursiveNodeEqual(lhs.Content[lindex], rhs.Content[rindex]) {
|
||||||
shouldInclude = false
|
shouldInclude = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if shouldInclude {
|
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
|
return lhs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||||
lhs.Node = unwrapDoc(lhs.Node)
|
lhs = lhs.unwrapDocument()
|
||||||
rhs.Node = unwrapDoc(rhs.Node)
|
rhs = rhs.unwrapDocument()
|
||||||
|
|
||||||
lhsNode := lhs.Node
|
lhsNode := lhs
|
||||||
|
|
||||||
if lhsNode.Tag == "!!null" {
|
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 {
|
switch lhsNode.Kind {
|
||||||
case yaml.MappingNode:
|
case MappingNode:
|
||||||
return nil, fmt.Errorf("maps not yet supported for subtraction")
|
return nil, fmt.Errorf("maps not yet supported for subtraction")
|
||||||
case yaml.SequenceNode:
|
case SequenceNode:
|
||||||
if rhs.Node.Kind != yaml.SequenceNode {
|
if rhs.Kind != SequenceNode {
|
||||||
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
|
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag)
|
||||||
}
|
}
|
||||||
return subtractArray(lhs, rhs)
|
return subtractArray(lhs, rhs)
|
||||||
case yaml.ScalarNode:
|
case ScalarNode:
|
||||||
if rhs.Node.Kind != yaml.ScalarNode {
|
if rhs.Kind != ScalarNode {
|
||||||
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Node.Tag, rhs.Path, lhsNode.Tag)
|
return nil, fmt.Errorf("%v (%v) cannot be subtracted from %v", rhs.Tag, rhs.GetNicePath(), lhsNode.Tag)
|
||||||
}
|
}
|
||||||
target.Node.Kind = yaml.ScalarNode
|
target.Kind = ScalarNode
|
||||||
target.Node.Style = lhsNode.Style
|
target.Style = lhsNode.Style
|
||||||
if err := subtractScalars(context, target, lhsNode, rhs.Node); err != nil {
|
if err := subtractScalars(context, target, lhsNode, rhs); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,19 +75,19 @@ func subtract(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *Ca
|
|||||||
return target, nil
|
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
|
lhsTag := lhs.Tag
|
||||||
rhsTag := rhs.Tag
|
rhsTag := rhs.Tag
|
||||||
lhsIsCustom := false
|
lhsIsCustom := false
|
||||||
if !strings.HasPrefix(lhsTag, "!!") {
|
if !strings.HasPrefix(lhsTag, "!!") {
|
||||||
// custom tag - we have to have a guess
|
// custom tag - we have to have a guess
|
||||||
lhsTag = guessTagFromCustomType(lhs)
|
lhsTag = lhs.guessTagFromCustomType()
|
||||||
lhsIsCustom = true
|
lhsIsCustom = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(rhsTag, "!!") {
|
if !strings.HasPrefix(rhsTag, "!!") {
|
||||||
// custom tag - we have to have a guess
|
// custom tag - we have to have a guess
|
||||||
rhsTag = guessTagFromCustomType(rhs)
|
rhsTag = rhs.guessTagFromCustomType()
|
||||||
}
|
}
|
||||||
|
|
||||||
isDateTime := lhsTag == "!!timestamp"
|
isDateTime := lhsTag == "!!timestamp"
|
||||||
@ -113,8 +111,8 @@ func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
result := lhsNum - rhsNum
|
result := lhsNum - rhsNum
|
||||||
target.Node.Tag = lhs.Tag
|
target.Tag = lhs.Tag
|
||||||
target.Node.Value = fmt.Sprintf(format, result)
|
target.Value = fmt.Sprintf(format, result)
|
||||||
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
} else if (lhsTag == "!!int" || lhsTag == "!!float") && (rhsTag == "!!int" || rhsTag == "!!float") {
|
||||||
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
lhsNum, err := strconv.ParseFloat(lhs.Value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,11 +124,11 @@ func subtractScalars(context Context, target *CandidateNode, lhs *yaml.Node, rhs
|
|||||||
}
|
}
|
||||||
result := lhsNum - rhsNum
|
result := lhsNum - rhsNum
|
||||||
if lhsIsCustom {
|
if lhsIsCustom {
|
||||||
target.Node.Tag = lhs.Tag
|
target.Tag = lhs.Tag
|
||||||
} else {
|
} else {
|
||||||
target.Node.Tag = "!!float"
|
target.Tag = "!!float"
|
||||||
}
|
}
|
||||||
target.Node.Value = fmt.Sprintf("%v", result)
|
target.Value = fmt.Sprintf("%v", result)
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("%v cannot be added to %v", lhs.Tag, rhs.Tag)
|
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
|
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
|
var durationStr string
|
||||||
if strings.HasPrefix(rhs.Value, "-") {
|
if strings.HasPrefix(rhs.Value, "-") {
|
||||||
durationStr = rhs.Value[1:]
|
durationStr = rhs.Value[1:]
|
||||||
@ -157,6 +155,6 @@ func subtractDateTime(layout string, target *CandidateNode, lhs *yaml.Node, rhs
|
|||||||
}
|
}
|
||||||
|
|
||||||
newTime := currentTime.Add(duration)
|
newTime := currentTime.Add(duration)
|
||||||
target.Node.Value = newTime.Format(layout)
|
target.Value = newTime.Format(layout)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -72,10 +72,7 @@ func variableLoopSingleChild(d *dataTreeNavigator, context Context, originalExp
|
|||||||
if prefs.IsReference {
|
if prefs.IsReference {
|
||||||
variableValue.PushBack(el.Value)
|
variableValue.PushBack(el.Value)
|
||||||
} else {
|
} else {
|
||||||
candidateCopy, err := el.Value.(*CandidateNode).Copy()
|
candidateCopy := el.Value.(*CandidateNode).Copy()
|
||||||
if err != nil {
|
|
||||||
return Context{}, err
|
|
||||||
}
|
|
||||||
variableValue.PushBack(candidateCopy)
|
variableValue.PushBack(candidateCopy)
|
||||||
}
|
}
|
||||||
newContext := context.ChildContext(context.MatchingNodes)
|
newContext := context.ChildContext(context.MatchingNodes)
|
||||||
|
@ -37,10 +37,7 @@ func compoundAssignFunction(d *dataTreeNavigator, context Context, expressionNod
|
|||||||
|
|
||||||
for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() {
|
for el := lhs.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
clone, err := candidate.Copy()
|
clone := candidate.Copy()
|
||||||
if err != nil {
|
|
||||||
return Context{}, err
|
|
||||||
}
|
|
||||||
valueCopyExp := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: clone}}
|
valueCopyExp := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: clone}}
|
||||||
|
|
||||||
valueExpression := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: candidate}}
|
valueExpression := &ExpressionNode{Operation: &Operation{OperationType: referenceOpType, CandidateNode: candidate}}
|
||||||
@ -187,8 +184,7 @@ func createBooleanCandidate(owner *CandidateNode, value bool) *CandidateNode {
|
|||||||
if !value {
|
if !value {
|
||||||
valString = "false"
|
valString = "false"
|
||||||
}
|
}
|
||||||
node := &yaml.Node{Kind: yaml.ScalarNode, Value: valString, Tag: "!!bool"}
|
return owner.CreateReplacement(ScalarNode, "!!bool", valString)
|
||||||
return owner.CreateReplacement(node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTraversalTree(path []interface{}, traversePrefs traversePreferences, targetKey bool) *ExpressionNode {
|
func createTraversalTree(path []interface{}, traversePrefs traversePreferences, targetKey bool) *ExpressionNode {
|
||||||
|
@ -7,8 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Printer interface {
|
type Printer interface {
|
||||||
@ -91,7 +89,7 @@ func (p *resultsPrinter) PrintedAnything() bool {
|
|||||||
return p.printedMatches
|
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" &&
|
p.printedMatches = p.printedMatches || (node.Tag != "!!null" &&
|
||||||
(node.Tag != "!!bool" || node.Value != "false"))
|
(node.Tag != "!!bool" || node.Value != "false"))
|
||||||
return p.encoder.Encode(writer, node)
|
return p.encoder.Encode(writer, node)
|
||||||
@ -161,7 +159,7 @@ func (p *resultsPrinter) PrintResults(matchingNodes *list.List) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.printNode(mappedDoc.Node, destination); err != nil {
|
if err := p.printNode(mappedDoc, destination); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user