mirror of
https://github.com/mikefarah/yq.git
synced 2024-12-19 20:19:04 +00:00
wip
This commit is contained in:
parent
66ab916c6b
commit
6e3f1d959e
@ -218,6 +218,19 @@ func (n *CandidateNode) CopyChildren() []*CandidateNode {
|
||||
}
|
||||
|
||||
func (n *CandidateNode) Copy() *CandidateNode {
|
||||
return n.doCopy(true)
|
||||
}
|
||||
|
||||
func (n *CandidateNode) CopyWithoutContent() *CandidateNode {
|
||||
return n.doCopy(false)
|
||||
}
|
||||
|
||||
func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
|
||||
var content []*CandidateNode
|
||||
if cloneContent {
|
||||
content = n.CopyChildren()
|
||||
}
|
||||
|
||||
return &CandidateNode{
|
||||
Kind: n.Kind,
|
||||
Style: n.Style,
|
||||
@ -229,7 +242,7 @@ func (n *CandidateNode) Copy() *CandidateNode {
|
||||
// ok not to clone this,
|
||||
// as its a reference to somewhere else.
|
||||
Alias: n.Alias,
|
||||
Content: n.CopyChildren(),
|
||||
Content: content,
|
||||
|
||||
HeadComment: n.HeadComment,
|
||||
LineComment: n.LineComment,
|
||||
|
@ -3,8 +3,6 @@ package yqlib
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func columnOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
@ -14,8 +12,11 @@ func columnOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", candidate.Node.Column), Tag: "!!int"}
|
||||
result := candidate.CreateReplacement(node)
|
||||
result := candidate.CreateReplacement()
|
||||
result.Kind = ScalarNode
|
||||
result.Value = fmt.Sprintf("%v", candidate.Column)
|
||||
result.Tag = "!!int"
|
||||
|
||||
results.PushBack(result)
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,6 @@ import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
"regexp"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type commentOpPreferences struct {
|
||||
@ -35,7 +33,7 @@ func assignCommentsOperator(d *dataTreeNavigator, context Context, expressionNod
|
||||
}
|
||||
|
||||
if rhs.MatchingNodes.Front() != nil {
|
||||
comment = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value
|
||||
comment = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,25 +47,25 @@ func assignCommentsOperator(d *dataTreeNavigator, context Context, expressionNod
|
||||
}
|
||||
|
||||
if rhs.MatchingNodes.Front() != nil {
|
||||
comment = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Value
|
||||
comment = rhs.MatchingNodes.Front().Value.(*CandidateNode).Value
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("Setting comment of : %v", candidate.GetKey())
|
||||
if preferences.LineComment {
|
||||
candidate.Node.LineComment = comment
|
||||
candidate.LineComment = comment
|
||||
}
|
||||
if preferences.HeadComment {
|
||||
candidate.Node.HeadComment = comment
|
||||
candidate.HeadComment = comment
|
||||
candidate.LeadingContent = "" // clobber the leading content, if there was any.
|
||||
}
|
||||
if preferences.FootComment && candidate.Node.Kind == yaml.DocumentNode && comment != "" {
|
||||
if preferences.FootComment && candidate.Kind == DocumentNode && comment != "" {
|
||||
candidate.TrailingContent = "# " + comment
|
||||
} else if preferences.FootComment && candidate.Node.Kind == yaml.DocumentNode {
|
||||
} else if preferences.FootComment && candidate.Kind == DocumentNode {
|
||||
candidate.TrailingContent = comment
|
||||
|
||||
} else if preferences.FootComment && candidate.Node.Kind != yaml.DocumentNode {
|
||||
candidate.Node.FootComment = comment
|
||||
} else if preferences.FootComment && candidate.Kind != DocumentNode {
|
||||
candidate.FootComment = comment
|
||||
candidate.TrailingContent = ""
|
||||
}
|
||||
|
||||
@ -91,7 +89,7 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
comment := ""
|
||||
if preferences.LineComment {
|
||||
comment = candidate.Node.LineComment
|
||||
comment = candidate.LineComment
|
||||
} else if preferences.HeadComment && candidate.LeadingContent != "" {
|
||||
var chompRegexp = regexp.MustCompile(`\n$`)
|
||||
var output bytes.Buffer
|
||||
@ -106,11 +104,11 @@ func getCommentsOperator(d *dataTreeNavigator, context Context, expressionNode *
|
||||
comment = output.String()
|
||||
comment = chompRegexp.ReplaceAllString(comment, "")
|
||||
} else if preferences.HeadComment {
|
||||
comment = candidate.Node.HeadComment
|
||||
} else if preferences.FootComment && candidate.Node.Kind == yaml.DocumentNode && candidate.TrailingContent != "" {
|
||||
comment = candidate.HeadComment
|
||||
} else if preferences.FootComment && candidate.Kind == DocumentNode && candidate.TrailingContent != "" {
|
||||
comment = candidate.TrailingContent
|
||||
} else if preferences.FootComment {
|
||||
comment = candidate.Node.FootComment
|
||||
comment = candidate.FootComment
|
||||
}
|
||||
comment = startCommentCharaterRegExp.ReplaceAllString(comment, "")
|
||||
comment = subsequentCommentCharaterRegExp.ReplaceAllString(comment, "\n")
|
||||
|
@ -2,8 +2,6 @@ package yqlib
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
@ -36,7 +34,11 @@ func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
|
||||
sequences.PushBack(sequenceNode)
|
||||
}
|
||||
|
||||
return context.SingleChildContext(&CandidateNode{Node: listToNodeSeq(sequences), Document: document, Path: path}), nil
|
||||
node := listToNodeSeq(sequences)
|
||||
node.Document = document
|
||||
node.Path = path
|
||||
|
||||
return context.SingleChildContext(node), nil
|
||||
|
||||
}
|
||||
|
||||
@ -53,33 +55,37 @@ func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateN
|
||||
|
||||
mapPairs, err := crossFunction(d, context.ChildContext(matches), expressionNode,
|
||||
func(d *dataTreeNavigator, context Context, lhs *CandidateNode, rhs *CandidateNode) (*CandidateNode, error) {
|
||||
node := yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
||||
node := CandidateNode{Kind: MappingNode, Tag: "!!map"}
|
||||
log.Debugf("LHS:", NodeToString(lhs))
|
||||
log.Debugf("RHS:", NodeToString(rhs))
|
||||
node.Content = []*yaml.Node{
|
||||
unwrapDoc(lhs.Node),
|
||||
unwrapDoc(rhs.Node),
|
||||
node.Content = []*CandidateNode{
|
||||
lhs.unwrapDocument(),
|
||||
rhs.unwrapDocument(),
|
||||
}
|
||||
node.Document = document
|
||||
node.Path = path
|
||||
|
||||
return &CandidateNode{Node: &node, Document: document, Path: path}, nil
|
||||
return &node, nil
|
||||
}, false)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
innerList := listToNodeSeq(mapPairs.MatchingNodes)
|
||||
innerList.Style = yaml.FlowStyle
|
||||
return &CandidateNode{Node: innerList, Document: document, Path: path}, nil
|
||||
innerList.Style = FlowStyle
|
||||
innerList.Document = document
|
||||
innerList.Path = path
|
||||
return innerList, nil
|
||||
}
|
||||
|
||||
// NOTE: here the document index gets dropped so we
|
||||
// no longer know where the node originates from.
|
||||
func listToNodeSeq(list *list.List) *yaml.Node {
|
||||
node := yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
|
||||
func listToNodeSeq(list *list.List) *CandidateNode {
|
||||
node := CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
|
||||
for entry := list.Front(); entry != nil; entry = entry.Next() {
|
||||
entryCandidate := entry.Value.(*CandidateNode)
|
||||
log.Debugf("Collecting %v into sequence", NodeToString(entryCandidate))
|
||||
node.Content = append(node.Content, entryCandidate.Node)
|
||||
node.Content = append(node.Content, entryCandidate)
|
||||
}
|
||||
return &node
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ func evalOperator(d *dataTreeNavigator, context Context, expressionNode *Express
|
||||
for pathExpStrEntry := pathExpStrResults.MatchingNodes.Front(); pathExpStrEntry != nil; pathExpStrEntry = pathExpStrEntry.Next() {
|
||||
expressionStrCandidate := pathExpStrEntry.Value.(*CandidateNode)
|
||||
|
||||
expressions[expIndex], err = ExpressionParser.ParseExpression(expressionStrCandidate.Node.Value)
|
||||
expressions[expIndex], err = ExpressionParser.ParseExpression(expressionStrCandidate.Value)
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ func filterOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
collected.Node.Style = unwrapDoc(candidate.Node).Style
|
||||
collected.Style = candidate.unwrapDocument().Style
|
||||
results.PushBack(collected)
|
||||
}
|
||||
return context.ChildContext(results), nil
|
||||
|
@ -3,8 +3,6 @@ package yqlib
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func lengthOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
@ -13,25 +11,27 @@ func lengthOperator(d *dataTreeNavigator, context Context, expressionNode *Expre
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
targetNode := unwrapDoc(candidate.Node)
|
||||
targetNode := candidate.unwrapDocument()
|
||||
var length int
|
||||
switch targetNode.Kind {
|
||||
case yaml.ScalarNode:
|
||||
case ScalarNode:
|
||||
if targetNode.Tag == "!!null" {
|
||||
length = 0
|
||||
} else {
|
||||
length = len(targetNode.Value)
|
||||
}
|
||||
case yaml.MappingNode:
|
||||
case MappingNode:
|
||||
length = len(targetNode.Content) / 2
|
||||
case yaml.SequenceNode:
|
||||
case SequenceNode:
|
||||
length = len(targetNode.Content)
|
||||
default:
|
||||
length = 0
|
||||
}
|
||||
|
||||
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", length), Tag: "!!int"}
|
||||
result := candidate.CreateReplacement(node)
|
||||
result := candidate.CreateReplacement()
|
||||
result.Kind = ScalarNode
|
||||
result.Value = fmt.Sprintf("%v", length)
|
||||
result.Tag = "!!int"
|
||||
results.PushBack(result)
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ package yqlib
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func lineOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||
@ -14,8 +12,10 @@ func lineOperator(d *dataTreeNavigator, context Context, expressionNode *Express
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
node := &yaml.Node{Kind: yaml.ScalarNode, Value: fmt.Sprintf("%v", candidate.Node.Line), Tag: "!!int"}
|
||||
result := candidate.CreateReplacement(node)
|
||||
result := candidate.CreateReplacement()
|
||||
result.Kind = ScalarNode
|
||||
result.Value = fmt.Sprintf("%v", candidate.Line)
|
||||
result.Tag = "!!int"
|
||||
results.PushBack(result)
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ func mapOperator(d *dataTreeNavigator, context Context, expressionNode *Expressi
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
collected.Node.Style = unwrapDoc(candidate.Node).Style
|
||||
collected.Style = candidate.unwrapDocument().Style
|
||||
|
||||
results.PushBack(collected)
|
||||
|
||||
|
@ -3,33 +3,31 @@ package yqlib
|
||||
import (
|
||||
"container/list"
|
||||
"fmt"
|
||||
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func pickMap(original *yaml.Node, indices *yaml.Node) *yaml.Node {
|
||||
func pickMap(original *CandidateNode, indices *CandidateNode) *CandidateNode {
|
||||
|
||||
filteredContent := make([]*yaml.Node, 0)
|
||||
filteredContent := make([]*CandidateNode, 0)
|
||||
for index := 0; index < len(indices.Content); index = index + 1 {
|
||||
keyToFind := indices.Content[index]
|
||||
|
||||
indexInMap := findKeyInMap(original, keyToFind)
|
||||
if indexInMap > -1 {
|
||||
clonedKey := deepClone(original.Content[indexInMap])
|
||||
clonedValue := deepClone(original.Content[indexInMap+1])
|
||||
clonedKey := original.Content[indexInMap].Copy()
|
||||
clonedValue := original.Content[indexInMap+1].Copy()
|
||||
filteredContent = append(filteredContent, clonedKey, clonedValue)
|
||||
}
|
||||
}
|
||||
|
||||
newNode := deepCloneNoContent(original)
|
||||
newNode := original.CopyWithoutContent()
|
||||
newNode.Content = filteredContent
|
||||
|
||||
return newNode
|
||||
}
|
||||
|
||||
func pickSequence(original *yaml.Node, indices *yaml.Node) (*yaml.Node, error) {
|
||||
func pickSequence(original *CandidateNode, indices *CandidateNode) (*CandidateNode, error) {
|
||||
|
||||
filteredContent := make([]*yaml.Node, 0)
|
||||
filteredContent := make([]*CandidateNode, 0)
|
||||
for index := 0; index < len(indices.Content); index = index + 1 {
|
||||
indexInArray, err := parseInt(indices.Content[index].Value)
|
||||
if err != nil {
|
||||
@ -37,11 +35,11 @@ func pickSequence(original *yaml.Node, indices *yaml.Node) (*yaml.Node, error) {
|
||||
}
|
||||
|
||||
if indexInArray > -1 && indexInArray < len(original.Content) {
|
||||
filteredContent = append(filteredContent, deepClone(original.Content[indexInArray]))
|
||||
filteredContent = append(filteredContent, original.Content[indexInArray].Copy())
|
||||
}
|
||||
}
|
||||
|
||||
newNode := deepCloneNoContent(original)
|
||||
newNode := original.CopyWithoutContent()
|
||||
newNode.Content = filteredContent
|
||||
|
||||
return newNode, nil
|
||||
@ -55,21 +53,21 @@ func pickOperator(d *dataTreeNavigator, context Context, expressionNode *Express
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
}
|
||||
indicesToPick := &yaml.Node{}
|
||||
indicesToPick := &CandidateNode{}
|
||||
if contextIndicesToPick.MatchingNodes.Len() > 0 {
|
||||
indicesToPick = contextIndicesToPick.MatchingNodes.Front().Value.(*CandidateNode).Node
|
||||
indicesToPick = contextIndicesToPick.MatchingNodes.Front().Value.(*CandidateNode)
|
||||
}
|
||||
|
||||
var results = list.New()
|
||||
|
||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||
candidate := el.Value.(*CandidateNode)
|
||||
node := unwrapDoc(candidate.Node)
|
||||
node := candidate.unwrapDocument()
|
||||
|
||||
var replacement *yaml.Node
|
||||
if node.Kind == yaml.MappingNode {
|
||||
var replacement *CandidateNode
|
||||
if node.Kind == MappingNode {
|
||||
replacement = pickMap(node, indicesToPick)
|
||||
} else if node.Kind == yaml.SequenceNode {
|
||||
} else if node.Kind == SequenceNode {
|
||||
replacement, err = pickSequence(node, indicesToPick)
|
||||
if err != nil {
|
||||
return Context{}, err
|
||||
@ -79,7 +77,9 @@ func pickOperator(d *dataTreeNavigator, context Context, expressionNode *Express
|
||||
return Context{}, fmt.Errorf("cannot pick indicies from type %v (%v)", node.Tag, candidate.GetNicePath())
|
||||
}
|
||||
|
||||
results.PushBack(candidate.CreateReplacementWithDocWrappers(replacement))
|
||||
replacement.LeadingContent = candidate.LeadingContent
|
||||
replacement.TrailingContent = candidate.TrailingContent
|
||||
results.PushBack(replacement)
|
||||
}
|
||||
|
||||
return context.ChildContext(results), nil
|
||||
|
Loading…
Reference in New Issue
Block a user