mirror of
https://github.com/mikefarah/yq.git
synced 2026-07-05 12:10:37 +00:00
Fixing TOML ArrayTable parsing issues #1758
This commit is contained in:
parent
306dc931a5
commit
39fbf01fa8
@ -267,6 +267,14 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
fullPath := dec.getFullPath(currentNode.Child())
|
fullPath := dec.getFullPath(currentNode.Child())
|
||||||
log.Debug("fullpath: %v", fullPath)
|
log.Debug("fullpath: %v", fullPath)
|
||||||
|
|
||||||
|
c := Context{}
|
||||||
|
c = c.SingleChildContext(dec.rootMap)
|
||||||
|
|
||||||
|
fullPath, err := getPathToUse(fullPath, dec, c)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Kind: MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
@ -275,7 +283,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
|
|
||||||
var tableValue *toml.Node
|
var tableValue *toml.Node
|
||||||
runAgainstCurrentExp := false
|
runAgainstCurrentExp := false
|
||||||
var err error
|
|
||||||
hasValue := dec.parser.NextExpression()
|
hasValue := dec.parser.NextExpression()
|
||||||
// check to see if there is any table data
|
// check to see if there is any table data
|
||||||
if hasValue {
|
if hasValue {
|
||||||
@ -292,8 +299,6 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c := Context{}
|
|
||||||
c = c.SingleChildContext(dec.rootMap)
|
|
||||||
err = dec.d.DeeplyAssign(c, fullPath, tableNodeValue)
|
err = dec.d.DeeplyAssign(c, fullPath, tableNodeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -324,35 +329,17 @@ func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error) {
|
func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error) {
|
||||||
log.Debug("c")
|
log.Debug("Enter processArrayTable")
|
||||||
fullPath := dec.getFullPath(currentNode.Child())
|
fullPath := dec.getFullPath(currentNode.Child())
|
||||||
log.Debug("Fullpath: %v", fullPath)
|
log.Debug("Fullpath: %v", fullPath)
|
||||||
|
|
||||||
c := Context{}
|
c := Context{}
|
||||||
c = c.SingleChildContext(dec.rootMap)
|
c = c.SingleChildContext(dec.rootMap)
|
||||||
|
|
||||||
pathToCheck := fullPath
|
fullPath, err := getPathToUse(fullPath, dec, c)
|
||||||
if len(fullPath) >= 1 {
|
|
||||||
pathToCheck = fullPath[:len(fullPath)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// if fullPath points to an array of maps rather than a map
|
|
||||||
// then it should set this element into the _last_ element of that array.
|
|
||||||
// Because TOML. So we'll inject the last index into the path.
|
|
||||||
readOp := createTraversalTree(pathToCheck, traversePreferences{DontAutoCreate: true}, false)
|
|
||||||
|
|
||||||
resultContext, err := dec.d.GetMatchingNodes(c, readOp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if resultContext.MatchingNodes.Len() >= 1 {
|
|
||||||
match := resultContext.MatchingNodes.Front().Value.(*CandidateNode)
|
|
||||||
// path refers to an array, we need to add this to the last element in the array
|
|
||||||
if match.Kind == SequenceNode {
|
|
||||||
fullPath = append(pathToCheck, len(match.Content)-1, fullPath[len(fullPath)-1])
|
|
||||||
log.Debugf("Adding to end of %v array, using path: %v", pathToCheck, fullPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to use the array append exp to add another entry to
|
// need to use the array append exp to add another entry to
|
||||||
// this array: fullpath += [ thing ]
|
// this array: fullpath += [ thing ]
|
||||||
@ -382,3 +369,29 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
|||||||
|
|
||||||
return runAgainstCurrentExp, err
|
return runAgainstCurrentExp, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if fullPath points to an array of maps rather than a map
|
||||||
|
// then it should set this element into the _last_ element of that array.
|
||||||
|
// Because TOML. So we'll inject the last index into the path.
|
||||||
|
|
||||||
|
func getPathToUse(fullPath []interface{}, dec *tomlDecoder, c Context) ([]interface{}, error) {
|
||||||
|
pathToCheck := fullPath
|
||||||
|
if len(fullPath) >= 1 {
|
||||||
|
pathToCheck = fullPath[:len(fullPath)-1]
|
||||||
|
}
|
||||||
|
readOp := createTraversalTree(pathToCheck, traversePreferences{DontAutoCreate: true}, false)
|
||||||
|
|
||||||
|
resultContext, err := dec.d.GetMatchingNodes(c, readOp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if resultContext.MatchingNodes.Len() >= 1 {
|
||||||
|
match := resultContext.MatchingNodes.Front().Value.(*CandidateNode)
|
||||||
|
// path refers to an array, we need to add this to the last element in the array
|
||||||
|
if match.Kind == SequenceNode {
|
||||||
|
fullPath = append(pathToCheck, len(match.Content)-1, fullPath[len(fullPath)-1])
|
||||||
|
log.Debugf("Adding to end of %v array, using path: %v", pathToCheck, fullPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fullPath, err
|
||||||
|
}
|
||||||
|
|||||||
@ -95,6 +95,20 @@ var emptyArrayTableThenTableExpected = `fruits:
|
|||||||
animals: {}
|
animals: {}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var arrayTableThenArray = `
|
||||||
|
[[rootA.kidB]]
|
||||||
|
cat = "meow"
|
||||||
|
|
||||||
|
[rootA.kidB.kidC]
|
||||||
|
dog = "bark"`
|
||||||
|
|
||||||
|
var arrayTableThenArrayExpected = `rootA:
|
||||||
|
kidB:
|
||||||
|
- cat: meow
|
||||||
|
kidC:
|
||||||
|
dog: bark
|
||||||
|
`
|
||||||
|
|
||||||
var sampleArrayTable = `
|
var sampleArrayTable = `
|
||||||
[owner.contact]
|
[owner.contact]
|
||||||
name = "Tom Preston-Werner"
|
name = "Tom Preston-Werner"
|
||||||
@ -341,6 +355,13 @@ var tomlScenarios = []formatScenario{
|
|||||||
expected: emptyArrayTableThenTableExpected,
|
expected: emptyArrayTableThenTableExpected,
|
||||||
scenarioType: "decode",
|
scenarioType: "decode",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Parse: Array of Array Table; then table",
|
||||||
|
input: arrayTableThenArray,
|
||||||
|
expected: arrayTableThenArrayExpected,
|
||||||
|
scenarioType: "decode",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "Parse: Empty Table",
|
description: "Parse: Empty Table",
|
||||||
input: emptyTable,
|
input: emptyTable,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user