mirror of
https://github.com/mikefarah/yq.git
synced 2025-03-10 02:58:54 +00:00
wip
This commit is contained in:
parent
4c6c653d25
commit
fe8f46d475
@ -81,7 +81,6 @@ type CandidateNode struct {
|
|||||||
LeadingContent string
|
LeadingContent string
|
||||||
TrailingContent string
|
TrailingContent string
|
||||||
|
|
||||||
Path []interface{} /// the path we took to get to this node
|
|
||||||
Document uint // the document index of this node
|
Document uint // the document index of this node
|
||||||
Filename string
|
Filename string
|
||||||
|
|
||||||
@ -95,13 +94,13 @@ 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)
|
// return fmt.Sprintf("%v%v - %v", keyPrefix, n.Document, n.Path)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (n *CandidateNode) unwrapDocument() *CandidateNode {
|
func (n *CandidateNode) unwrapDocument() *CandidateNode {
|
||||||
if n.Kind == DocumentNode {
|
if n.Kind == DocumentNode {
|
||||||
@ -114,15 +113,47 @@ func (n *CandidateNode) GetNiceTag() string {
|
|||||||
return n.unwrapDocument().Tag
|
return n.unwrapDocument().Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *CandidateNode) getParsedKey() interface{} {
|
||||||
|
if n.Key == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if n.Key.Tag == "!!str" {
|
||||||
|
return n.Key.Value
|
||||||
|
}
|
||||||
|
index, err := parseInt(n.Key.Value)
|
||||||
|
if err != nil {
|
||||||
|
return n.Key.Value
|
||||||
|
}
|
||||||
|
return index
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *CandidateNode) GetPath() []interface{} {
|
||||||
|
if n.Parent != nil {
|
||||||
|
return append(n.Parent.GetPath(), n.getParsedKey())
|
||||||
|
}
|
||||||
|
return []interface{}{n.getParsedKey()}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) GetNicePath() string {
|
func (n *CandidateNode) GetNicePath() string {
|
||||||
if n.Path != nil && len(n.Path) >= 0 {
|
var sb strings.Builder
|
||||||
pathStr := make([]string, len(n.Path))
|
path := n.GetPath()
|
||||||
for i, v := range n.Path {
|
for i, element := range path {
|
||||||
pathStr[i] = fmt.Sprintf("%v", v)
|
elementStr := fmt.Sprintf("%v", element)
|
||||||
|
switch element.(type) {
|
||||||
|
case int:
|
||||||
|
sb.WriteString("[" + elementStr + "]")
|
||||||
|
default:
|
||||||
|
if i == 0 {
|
||||||
|
sb.WriteString(elementStr)
|
||||||
|
} else if strings.ContainsRune(elementStr, '.') {
|
||||||
|
sb.WriteString("[" + elementStr + "]")
|
||||||
|
} else {
|
||||||
|
sb.WriteString("." + elementStr)
|
||||||
}
|
}
|
||||||
return strings.Join(pathStr, ".")
|
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return sb.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) AsList() *list.List {
|
func (n *CandidateNode) AsList() *list.List {
|
||||||
@ -178,7 +209,6 @@ func (n *CandidateNode) guessTagFromCustomType() string {
|
|||||||
|
|
||||||
func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *CandidateNode {
|
func (n *CandidateNode) CreateReplacement(kind Kind, tag string, value string) *CandidateNode {
|
||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Path: n.createChildPath(nil),
|
|
||||||
Parent: n.Parent,
|
Parent: n.Parent,
|
||||||
Key: n.Key,
|
Key: n.Key,
|
||||||
IsMapKey: n.IsMapKey,
|
IsMapKey: n.IsMapKey,
|
||||||
@ -199,20 +229,6 @@ func (n *CandidateNode) CreateReplacementWithDocWrappers(kind Kind, tag string,
|
|||||||
return replacement
|
return replacement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) createChildPath(path interface{}) []interface{} {
|
|
||||||
if path == nil {
|
|
||||||
newPath := make([]interface{}, len(n.Path))
|
|
||||||
copy(newPath, n.Path)
|
|
||||||
return newPath
|
|
||||||
}
|
|
||||||
|
|
||||||
//don't use append as they may actually modify the path of the orignal node!
|
|
||||||
newPath := make([]interface{}, len(n.Path)+1)
|
|
||||||
copy(newPath, n.Path)
|
|
||||||
newPath[len(n.Path)] = path
|
|
||||||
return newPath
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *CandidateNode) CopyChildren() []*CandidateNode {
|
func (n *CandidateNode) CopyChildren() []*CandidateNode {
|
||||||
clonedKids := make([]*CandidateNode, len(n.Content))
|
clonedKids := make([]*CandidateNode, len(n.Content))
|
||||||
for i, child := range n.Content {
|
for i, child := range n.Content {
|
||||||
@ -258,7 +274,6 @@ func (n *CandidateNode) doCopy(cloneContent bool) *CandidateNode {
|
|||||||
LeadingContent: n.LeadingContent,
|
LeadingContent: n.LeadingContent,
|
||||||
TrailingContent: n.TrailingContent,
|
TrailingContent: n.TrailingContent,
|
||||||
|
|
||||||
Path: n.Path,
|
|
||||||
Document: n.Document,
|
Document: n.Document,
|
||||||
Filename: n.Filename,
|
Filename: n.Filename,
|
||||||
|
|
||||||
@ -290,7 +305,7 @@ func (n *CandidateNode) UpdateFrom(other *CandidateNode, prefs assignPreferences
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignPreferences) {
|
func (n *CandidateNode) UpdateAttributesFrom(other *CandidateNode, prefs assignPreferences) {
|
||||||
log.Debug("UpdateAttributesFrom: n: %v other: %v", n.GetKey(), other.GetKey())
|
log.Debug("UpdateAttributesFrom: n: %v other: %v", n.Key.Value, other.Key.Value)
|
||||||
if n.Kind != other.Kind {
|
if n.Kind != other.Kind {
|
||||||
// clear out the contents when switching to a different type
|
// clear out the contents when switching to a different type
|
||||||
// e.g. map to array
|
// e.g. map to array
|
||||||
|
@ -12,7 +12,7 @@ type DataTreeNavigator interface {
|
|||||||
// a new context of matching candidates
|
// a new context of matching candidates
|
||||||
GetMatchingNodes(context Context, expressionNode *ExpressionNode) (Context, error)
|
GetMatchingNodes(context Context, expressionNode *ExpressionNode) (Context, error)
|
||||||
|
|
||||||
DeeplyAssign(context Context, rhsNode *CandidateNode) error
|
DeeplyAssign(context Context, path []interface{}, rhsNode *CandidateNode) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type dataTreeNavigator struct {
|
type dataTreeNavigator struct {
|
||||||
@ -22,7 +22,7 @@ func NewDataTreeNavigator() DataTreeNavigator {
|
|||||||
return &dataTreeNavigator{}
|
return &dataTreeNavigator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dataTreeNavigator) DeeplyAssign(context Context, rhsCandidateNode *CandidateNode) error {
|
func (d *dataTreeNavigator) DeeplyAssign(context Context, path []interface{}, rhsCandidateNode *CandidateNode) error {
|
||||||
|
|
||||||
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ func (d *dataTreeNavigator) DeeplyAssign(context Context, rhsCandidateNode *Cand
|
|||||||
|
|
||||||
assignmentOpNode := &ExpressionNode{
|
assignmentOpNode := &ExpressionNode{
|
||||||
Operation: assignmentOp,
|
Operation: assignmentOp,
|
||||||
LHS: createTraversalTree(rhsCandidateNode.Path, traversePreferences{}, false),
|
LHS: createTraversalTree(path, traversePreferences{}, false),
|
||||||
RHS: &ExpressionNode{Operation: rhsOp},
|
RHS: &ExpressionNode{Operation: rhsOp},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@ func (dec *propertiesDecoder) applyPropertyComments(context Context, path []inte
|
|||||||
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
||||||
|
|
||||||
rhsCandidateNode := &CandidateNode{
|
rhsCandidateNode := &CandidateNode{
|
||||||
Path: path,
|
|
||||||
Tag: "!!str",
|
Tag: "!!str",
|
||||||
Value: fmt.Sprintf("%v", path[len(path)-1]),
|
Value: fmt.Sprintf("%v", path[len(path)-1]),
|
||||||
HeadComment: dec.processComment(strings.Join(comments, "\n")),
|
HeadComment: dec.processComment(strings.Join(comments, "\n")),
|
||||||
@ -86,9 +85,8 @@ func (dec *propertiesDecoder) applyProperty(context Context, properties *propert
|
|||||||
|
|
||||||
rhsNode := createStringScalarNode(value)
|
rhsNode := createStringScalarNode(value)
|
||||||
rhsNode.Tag = rhsNode.guessTagFromCustomType()
|
rhsNode.Tag = rhsNode.guessTagFromCustomType()
|
||||||
rhsNode.Path = path
|
|
||||||
|
|
||||||
return dec.d.DeeplyAssign(context, rhsNode)
|
return dec.d.DeeplyAssign(context, path, rhsNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
|
func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
|
||||||
|
@ -62,12 +62,11 @@ func (dec *tomlDecoder) processKeyValueIntoMap(rootMap *CandidateNode, tomlNode
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
valueNode.Path = path
|
|
||||||
|
|
||||||
context := Context{}
|
context := Context{}
|
||||||
context = context.SingleChildContext(rootMap)
|
context = context.SingleChildContext(rootMap)
|
||||||
|
|
||||||
return dec.d.DeeplyAssign(context, valueNode)
|
return dec.d.DeeplyAssign(context, path, valueNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode *toml.Node) (bool, error) {
|
func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode *toml.Node) (bool, error) {
|
||||||
@ -279,7 +278,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
Path: fullPath,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tableValue := dec.parser.Expression()
|
tableValue := dec.parser.Expression()
|
||||||
@ -296,7 +294,7 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
c := Context{}
|
c := Context{}
|
||||||
|
|
||||||
c = c.SingleChildContext(dec.rootMap)
|
c = c.SingleChildContext(dec.rootMap)
|
||||||
err = dec.d.DeeplyAssign(c, tableNodeValue)
|
err = dec.d.DeeplyAssign(c, fullPath, tableNodeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -305,7 +303,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
|
|
||||||
func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode *CandidateNode) error {
|
func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode *CandidateNode) error {
|
||||||
rhsCandidateNode := &CandidateNode{
|
rhsCandidateNode := &CandidateNode{
|
||||||
Path: path,
|
|
||||||
Kind: SequenceNode,
|
Kind: SequenceNode,
|
||||||
Tag: "!!seq",
|
Tag: "!!seq",
|
||||||
Content: []*CandidateNode{rhsNode},
|
Content: []*CandidateNode{rhsNode},
|
||||||
@ -341,7 +338,6 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
|||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
Path: fullPath,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tableValue := dec.parser.Expression()
|
tableValue := dec.parser.Expression()
|
||||||
|
@ -10,8 +10,6 @@ func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
|
|||||||
//each matchingNodes entry should turn into a sequence of keys to create.
|
//each matchingNodes entry should turn into a sequence of keys to create.
|
||||||
//then collect object should do a cross function of the same index sequence for all matches.
|
//then collect object should do a cross function of the same index sequence for all matches.
|
||||||
|
|
||||||
var path []interface{}
|
|
||||||
|
|
||||||
var document uint
|
var document uint
|
||||||
|
|
||||||
sequences := list.New()
|
sequences := list.New()
|
||||||
@ -36,19 +34,16 @@ func createMapOperator(d *dataTreeNavigator, context Context, expressionNode *Ex
|
|||||||
|
|
||||||
node := listToNodeSeq(sequences)
|
node := listToNodeSeq(sequences)
|
||||||
node.Document = document
|
node.Document = document
|
||||||
node.Path = path
|
|
||||||
|
|
||||||
return context.SingleChildContext(node), nil
|
return context.SingleChildContext(node), nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateNode, expressionNode *ExpressionNode) (*CandidateNode, error) {
|
func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateNode, expressionNode *ExpressionNode) (*CandidateNode, error) {
|
||||||
var path []interface{}
|
|
||||||
var document uint
|
var document uint
|
||||||
var matches = list.New()
|
var matches = list.New()
|
||||||
|
|
||||||
if matchingNode != nil {
|
if matchingNode != nil {
|
||||||
path = matchingNode.Path
|
|
||||||
document = matchingNode.Document
|
document = matchingNode.Document
|
||||||
matches.PushBack(matchingNode)
|
matches.PushBack(matchingNode)
|
||||||
}
|
}
|
||||||
@ -63,7 +58,6 @@ func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateN
|
|||||||
rhs.unwrapDocument(),
|
rhs.unwrapDocument(),
|
||||||
}
|
}
|
||||||
node.Document = document
|
node.Document = document
|
||||||
node.Path = path
|
|
||||||
|
|
||||||
return &node, nil
|
return &node, nil
|
||||||
}, false)
|
}, false)
|
||||||
@ -74,7 +68,6 @@ func sequenceFor(d *dataTreeNavigator, context Context, matchingNode *CandidateN
|
|||||||
innerList := listToNodeSeq(mapPairs.MatchingNodes)
|
innerList := listToNodeSeq(mapPairs.MatchingNodes)
|
||||||
innerList.Style = FlowStyle
|
innerList.Style = FlowStyle
|
||||||
innerList.Document = document
|
innerList.Document = document
|
||||||
innerList.Path = path
|
|
||||||
return innerList, nil
|
return innerList, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +88,9 @@ func formatDateTime(d *dataTreeNavigator, context Context, expressionNode *Expre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.Document = candidate.Document
|
node.Document = candidate.Document
|
||||||
|
node.Parent = candidate.Parent
|
||||||
|
node.Key = candidate.Key
|
||||||
node.FileIndex = candidate.FileIndex
|
node.FileIndex = candidate.FileIndex
|
||||||
node.Path = candidate.Path
|
|
||||||
results.PushBack(node)
|
results.PushBack(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@ func deleteChildOperator(d *dataTreeNavigator, context Context, expressionNode *
|
|||||||
}
|
}
|
||||||
|
|
||||||
parentNode := candidate.Parent
|
parentNode := candidate.Parent
|
||||||
childPath := candidate.Path[len(candidate.Path)-1]
|
parentPath := parentNode.GetPath()
|
||||||
|
childPath := parentPath[len(parentPath)-1]
|
||||||
|
|
||||||
if parentNode.Kind == MappingNode {
|
if parentNode.Kind == MappingNode {
|
||||||
deleteFromMap(candidate.Parent, childPath)
|
deleteFromMap(candidate.Parent, childPath)
|
||||||
@ -60,7 +61,7 @@ func deleteFromMap(candidate *CandidateNode, childPath interface{}) {
|
|||||||
|
|
||||||
shouldDelete := key.Value == childPath
|
shouldDelete := key.Value == childPath
|
||||||
|
|
||||||
log.Debugf("shouldDelete %v ? %v", value.GetKey(), shouldDelete)
|
log.Debugf("shouldDelete %v ? %v", value.ToDebugString(), shouldDelete)
|
||||||
|
|
||||||
if !shouldDelete {
|
if !shouldDelete {
|
||||||
newContents = append(newContents, key, value)
|
newContents = append(newContents, key, value)
|
||||||
|
@ -156,9 +156,11 @@ func getPathOperator(d *dataTreeNavigator, context Context, expressionNode *Expr
|
|||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
node := candidate.CreateReplacement(SequenceNode, "!!seq", "")
|
node := candidate.CreateReplacement(SequenceNode, "!!seq", "")
|
||||||
|
|
||||||
content := make([]*CandidateNode, len(candidate.Path))
|
path := candidate.GetPath()
|
||||||
for pathIndex := 0; pathIndex < len(candidate.Path); pathIndex++ {
|
|
||||||
path := candidate.Path[pathIndex]
|
content := make([]*CandidateNode, len(path))
|
||||||
|
for pathIndex := 0; pathIndex < len(path); pathIndex++ {
|
||||||
|
path := path[pathIndex]
|
||||||
content[pathIndex] = createPathNodeFor(path)
|
content[pathIndex] = createPathNodeFor(path)
|
||||||
}
|
}
|
||||||
node.Content = content
|
node.Content = content
|
||||||
|
Loading…
Reference in New Issue
Block a user