mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
Deep splat!
This commit is contained in:
parent
8a6af1720d
commit
4dbdd4a805
@ -112,6 +112,24 @@ func TestReadArrayCmd(t *testing.T) {
|
||||
test.AssertResult(t, "b.e.1.name: sam\n", result.Output)
|
||||
}
|
||||
|
||||
func TestReadDeepSplatCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "read -p kv examples/sample.yaml b.**")
|
||||
if result.Error != nil {
|
||||
t.Error(result.Error)
|
||||
}
|
||||
expectedOutput := `b.c: 2
|
||||
b.d.[0]: 3
|
||||
b.d.[1]: 4
|
||||
b.d.[2]: 5
|
||||
b.e.[0].name: fred
|
||||
b.e.[0].value: 3
|
||||
b.e.[1].name: sam
|
||||
b.e.[1].value: 4
|
||||
`
|
||||
test.AssertResult(t, expectedOutput, result.Output)
|
||||
}
|
||||
|
||||
func TestReadWithKeyCmd(t *testing.T) {
|
||||
cmd := getRootCommand()
|
||||
result := test.RunCmd(cmd, "read -p k examples/sample.yaml b.c")
|
||||
|
@ -31,13 +31,19 @@ func (n *navigator) Traverse(value *yaml.Node, path []string) error {
|
||||
return n.doTraverse(value, "", path, emptyArray)
|
||||
}
|
||||
|
||||
func (n *navigator) doTraverse(value *yaml.Node, head string, path []string, pathStack []interface{}) error {
|
||||
if len(path) > 0 {
|
||||
log.Debugf("diving into %v", path[0])
|
||||
DebugNode(value)
|
||||
return n.recurse(value, path[0], path[1:], pathStack)
|
||||
func (n *navigator) doTraverse(value *yaml.Node, head string, tail []string, pathStack []interface{}) error {
|
||||
log.Debug("head %v", head)
|
||||
DebugNode(value)
|
||||
if head == "**" && value.Kind != yaml.ScalarNode {
|
||||
return n.recurse(value, head, tail, pathStack)
|
||||
}
|
||||
return n.navigationStrategy.Visit(NewNodeContext(value, head, path, pathStack))
|
||||
|
||||
if len(tail) > 0 {
|
||||
log.Debugf("diving into %v", tail[0])
|
||||
DebugNode(value)
|
||||
return n.recurse(value, tail[0], tail[1:], pathStack)
|
||||
}
|
||||
return n.navigationStrategy.Visit(NewNodeContext(value, head, tail, pathStack))
|
||||
}
|
||||
|
||||
func (n *navigator) getOrReplace(original *yaml.Node, expectedKind yaml.Kind) *yaml.Node {
|
||||
@ -56,8 +62,8 @@ 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!, %v", len(value.Content))
|
||||
if head == "*" {
|
||||
return n.splatArray(value, tail, pathStack)
|
||||
if head == "*" || head == "**" {
|
||||
return n.splatArray(value, head, tail, pathStack)
|
||||
} else if head == "+" {
|
||||
return n.appendArray(value, tail, pathStack)
|
||||
}
|
||||
@ -196,11 +202,11 @@ func (n *navigator) visitAliasSequence(possibleAliasArray []*yaml.Node, head str
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *navigator) splatArray(value *yaml.Node, tail []string, pathStack []interface{}) error {
|
||||
func (n *navigator) splatArray(value *yaml.Node, head string, tail []string, pathStack []interface{}) error {
|
||||
for index, childValue := range value.Content {
|
||||
log.Debug("processing")
|
||||
DebugNode(childValue)
|
||||
head := fmt.Sprintf("%v", index)
|
||||
// head = fmt.Sprintf("%v", index)
|
||||
childValue = n.getOrReplace(childValue, guessKind(tail, childValue.Kind))
|
||||
var err = n.doTraverse(childValue, head, tail, append(pathStack, index))
|
||||
if err != nil {
|
||||
|
@ -61,7 +61,7 @@ func guessKind(tail []string, guess yaml.Kind) yaml.Kind {
|
||||
if tail[0] == "+" || errorParsingInt == nil {
|
||||
return yaml.SequenceNode
|
||||
}
|
||||
if tail[0] == "*" && (guess == yaml.SequenceNode || guess == yaml.MappingNode) {
|
||||
if (tail[0] == "*" || tail[0] == "**") && (guess == yaml.SequenceNode || guess == yaml.MappingNode) {
|
||||
return guess
|
||||
}
|
||||
if guess == yaml.AliasNode {
|
||||
|
@ -74,13 +74,12 @@ func (ns *NavigationStrategyImpl) ShouldTraverse(nodeContext NodeContext, nodeKe
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) shouldVisit(nodeContext NodeContext) bool {
|
||||
// we should traverse aliases (if enabled), but not visit them :/
|
||||
pathStack := nodeContext.PathStack
|
||||
if len(pathStack) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if ns.alreadyVisited(pathStack) {
|
||||
if ns.alreadyVisited(pathStack) || len(nodeContext.Tail) != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -108,7 +107,7 @@ func (ns *NavigationStrategyImpl) Visit(nodeContext NodeContext) error {
|
||||
}
|
||||
|
||||
func (ns *NavigationStrategyImpl) DebugVisitedNodes() {
|
||||
log.Debug("%v", ns.visitedNodes)
|
||||
log.Debug("Visited Nodes:")
|
||||
for _, candidate := range ns.visitedNodes {
|
||||
log.Debug(" - %v", PathStackToString(candidate.PathStack))
|
||||
}
|
||||
|
@ -24,6 +24,9 @@ func NewPathParser() PathParser {
|
||||
*/
|
||||
func (p *pathParser) MatchesNextPathElement(nodeContext NodeContext, nodeKey string) bool {
|
||||
head := nodeContext.Head
|
||||
if head == "**" || head == "*" {
|
||||
return true
|
||||
}
|
||||
var prefixMatch = strings.TrimSuffix(head, "*")
|
||||
if prefixMatch != head {
|
||||
log.Debug("prefix match, %v", strings.HasPrefix(nodeKey, prefixMatch))
|
||||
|
Loading…
Reference in New Issue
Block a user