mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Extracted out is path expression checking logic
This commit is contained in:
parent
2d237e7e8e
commit
35fd5b7ae4
@ -2,7 +2,6 @@ package yqlib
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
errors "github.com/pkg/errors"
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
@ -70,7 +69,7 @@ func (n *navigator) recurse(value *yaml.Node, head string, tail []string, pathSt
|
||||
return n.recurseMap(value, head, tail, pathStack)
|
||||
case yaml.SequenceNode:
|
||||
log.Debug("its a sequence of %v things!", len(value.Content))
|
||||
if head == "*" || head == "**" || strings.Contains(head, "==") {
|
||||
if n.navigationStrategy.GetPathParser().IsPathExpression(head) {
|
||||
return n.splatArray(value, head, tail, pathStack)
|
||||
} else if head == "+" {
|
||||
return n.appendArray(value, head, tail, pathStack)
|
||||
@ -117,7 +116,7 @@ func (n *navigator) recurseMap(value *yaml.Node, head string, tail []string, pat
|
||||
return errorVisiting
|
||||
}
|
||||
|
||||
if traversedEntry || head == "*" || head == "**" || !n.navigationStrategy.AutoCreateMap(NewNodeContext(value, head, tail, pathStack)) {
|
||||
if traversedEntry || n.navigationStrategy.GetPathParser().IsPathExpression(head) || !n.navigationStrategy.AutoCreateMap(NewNodeContext(value, head, tail, pathStack)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ func DeleteNavigationStrategy(pathElementToDelete string) NavigationStrategy {
|
||||
parser := NewPathParser()
|
||||
return &NavigationStrategyImpl{
|
||||
visitedNodes: []*NodeContext{},
|
||||
pathParser: parser,
|
||||
followAlias: func(nodeContext NodeContext) bool {
|
||||
return false
|
||||
},
|
||||
|
@ -3,6 +3,7 @@ package yqlib
|
||||
func FilterMatchingNodesNavigationStrategy(value string) NavigationStrategy {
|
||||
return &NavigationStrategyImpl{
|
||||
visitedNodes: []*NodeContext{},
|
||||
pathParser: NewPathParser(),
|
||||
followAlias: func(nodeContext NodeContext) bool {
|
||||
return true
|
||||
},
|
||||
|
@ -74,7 +74,8 @@ func guessKind(head string, tail []string, guess yaml.Kind) yaml.Kind {
|
||||
if tail[0] == "+" || errorParsingInt == nil {
|
||||
return yaml.SequenceNode
|
||||
}
|
||||
if (tail[0] == "*" || tail[0] == "**" || head == "**") && (guess == yaml.SequenceNode || guess == yaml.MappingNode) {
|
||||
pathParser := NewPathParser()
|
||||
if (pathParser.IsPathExpression(tail[0]) || head == "**") && (guess == yaml.SequenceNode || guess == yaml.MappingNode) {
|
||||
return guess
|
||||
}
|
||||
if guess == yaml.AliasNode {
|
||||
|
@ -36,6 +36,7 @@ type NavigationStrategy interface {
|
||||
ShouldTraverse(nodeContext NodeContext, nodeKey string) bool
|
||||
GetVisitedNodes() []*NodeContext
|
||||
DebugVisitedNodes()
|
||||
GetPathParser() PathParser
|
||||
}
|
||||
|
||||
type NavigationStrategyImpl struct {
|
||||
@ -44,6 +45,11 @@ type NavigationStrategyImpl struct {
|
||||
visit func(nodeContext NodeContext) error
|
||||
shouldVisitExtraFn func(nodeContext NodeContext) bool
|
||||
visitedNodes []*NodeContext
|
||||
pathParser PathParser
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) GetPathParser() PathParser {
|
||||
return ns.pathParser
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) GetVisitedNodes() []*NodeContext {
|
||||
@ -68,10 +74,8 @@ func (ns *NavigationStrategyImpl) ShouldTraverse(nodeContext NodeContext, nodeKe
|
||||
return false
|
||||
}
|
||||
|
||||
parser := NewPathParser()
|
||||
|
||||
return (nodeKey == "<<" && ns.FollowAlias(nodeContext)) || (nodeKey != "<<" &&
|
||||
parser.MatchesNextPathElement(nodeContext, nodeKey))
|
||||
ns.pathParser.MatchesNextPathElement(nodeContext, nodeKey))
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) shouldVisit(nodeContext NodeContext) bool {
|
||||
@ -88,11 +92,10 @@ func (ns *NavigationStrategyImpl) shouldVisit(nodeContext NodeContext) bool {
|
||||
|
||||
nodeKey := fmt.Sprintf("%v", pathStack[len(pathStack)-1])
|
||||
log.Debug("nodeKey: %v, nodeContext.Head: %v", nodeKey, nodeContext.Head)
|
||||
parser := NewPathParser()
|
||||
|
||||
// only visit aliases if its an exact match
|
||||
return ((nodeKey == "<<" && nodeContext.Head == "<<") || (nodeKey != "<<" &&
|
||||
parser.MatchesNextPathElement(nodeContext, nodeKey))) && (ns.shouldVisitExtraFn == nil || ns.shouldVisitExtraFn(nodeContext))
|
||||
ns.pathParser.MatchesNextPathElement(nodeContext, nodeKey))) && (ns.shouldVisitExtraFn == nil || ns.shouldVisitExtraFn(nodeContext))
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) Visit(nodeContext NodeContext) error {
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
type PathParser interface {
|
||||
ParsePath(path string) []string
|
||||
MatchesNextPathElement(nodeContext NodeContext, nodeKey string) bool
|
||||
IsPathExpression(pathElement string) bool
|
||||
}
|
||||
|
||||
type pathParser struct{}
|
||||
@ -16,6 +17,10 @@ func NewPathParser() PathParser {
|
||||
return &pathParser{}
|
||||
}
|
||||
|
||||
func (p *pathParser) IsPathExpression(pathElement string) bool {
|
||||
return pathElement == "*" || pathElement == "**" || strings.Contains(pathElement, "==")
|
||||
}
|
||||
|
||||
/**
|
||||
* node: node that we may traverse/visit
|
||||
* head: path element expression to match against
|
||||
|
@ -3,6 +3,7 @@ package yqlib
|
||||
func ReadNavigationStrategy() NavigationStrategy {
|
||||
return &NavigationStrategyImpl{
|
||||
visitedNodes: []*NodeContext{},
|
||||
pathParser: NewPathParser(),
|
||||
followAlias: func(nodeContext NodeContext) bool {
|
||||
return true
|
||||
},
|
||||
|
@ -3,6 +3,7 @@ package yqlib
|
||||
func UpdateNavigationStrategy(updateCommand UpdateCommand, autoCreate bool) NavigationStrategy {
|
||||
return &NavigationStrategyImpl{
|
||||
visitedNodes: []*NodeContext{},
|
||||
pathParser: NewPathParser(),
|
||||
followAlias: func(nodeContext NodeContext) bool {
|
||||
return false
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user