mirror of
https://github.com/mikefarah/yq.git
synced 2025-01-28 01:15:35 +00:00
wip
This commit is contained in:
parent
6a891e5239
commit
8fef31b417
@ -35,6 +35,13 @@ func createIntegerScalarNode(num int) *CandidateNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createStringScalarNode(stringValue string) *CandidateNode {
|
||||||
|
var node = &CandidateNode{Kind: ScalarNode}
|
||||||
|
node.Value = stringValue
|
||||||
|
node.Tag = "!!str"
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
func createScalarNode(value interface{}, stringValue string) *CandidateNode {
|
func createScalarNode(value interface{}, stringValue string) *CandidateNode {
|
||||||
var node = &CandidateNode{Kind: ScalarNode}
|
var node = &CandidateNode{Kind: ScalarNode}
|
||||||
node.Value = stringValue
|
node.Value = stringValue
|
||||||
@ -137,36 +144,37 @@ func (n *CandidateNode) guessTagFromCustomType() string {
|
|||||||
log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading)
|
log.Debug("guessTagFromCustomType: could not guess underlying tag type %v", errorReading)
|
||||||
return n.Tag
|
return n.Tag
|
||||||
}
|
}
|
||||||
guessedTag := unwrapDoc(dataBucket).Tag
|
guessedTag := dataBucket.unwrapDocument().Tag
|
||||||
log.Info("im guessing the tag %v is a %v", n.Tag, guessedTag)
|
log.Info("im guessing the tag %v is a %v", n.Tag, guessedTag)
|
||||||
return guessedTag
|
return guessedTag
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *CandidateNode) CreateChildInMap(key *CandidateNode) *CandidateNode {
|
// func (n *CandidateNode) CreateChildInMap(key *CandidateNode) *CandidateNode {
|
||||||
var value interface{}
|
// var value interface{}
|
||||||
if key != nil {
|
// if key != nil {
|
||||||
value = key.Value
|
// value = key.Value
|
||||||
}
|
// }
|
||||||
return &CandidateNode{
|
// return &CandidateNode{
|
||||||
Path: n.createChildPath(value),
|
// Path: n.createChildPath(value),
|
||||||
Parent: n,
|
// Parent: n,
|
||||||
Key: key,
|
// Key: key,
|
||||||
Document: n.Document,
|
|
||||||
Filename: n.Filename,
|
|
||||||
FileIndex: n.FileIndex,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *CandidateNode) CreateChildInArray(index int) *CandidateNode {
|
// Document: n.Document,
|
||||||
return &CandidateNode{
|
// Filename: n.Filename,
|
||||||
Path: n.createChildPath(index),
|
// FileIndex: n.FileIndex,
|
||||||
Parent: n,
|
// }
|
||||||
Key: createIntegerScalarNode(index),
|
// }
|
||||||
Document: n.Document,
|
|
||||||
Filename: n.Filename,
|
// func (n *CandidateNode) CreateChildInArray(index int) *CandidateNode {
|
||||||
FileIndex: n.FileIndex,
|
// return &CandidateNode{
|
||||||
}
|
// Path: n.createChildPath(index),
|
||||||
}
|
// Parent: n,
|
||||||
|
// Key: createIntegerScalarNode(index),
|
||||||
|
// Document: n.Document,
|
||||||
|
// Filename: n.Filename,
|
||||||
|
// FileIndex: n.FileIndex,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
func (n *CandidateNode) CreateReplacement() *CandidateNode {
|
func (n *CandidateNode) CreateReplacement() *CandidateNode {
|
||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
logging "gopkg.in/op/go-logging.v1"
|
logging "gopkg.in/op/go-logging.v1"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataTreeNavigator interface {
|
type DataTreeNavigator interface {
|
||||||
@ -13,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, path []interface{}, rhsNode *yaml.Node) error
|
DeeplyAssign(context Context, rhsNode *CandidateNode) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type dataTreeNavigator struct {
|
type dataTreeNavigator struct {
|
||||||
@ -23,12 +22,7 @@ func NewDataTreeNavigator() DataTreeNavigator {
|
|||||||
return &dataTreeNavigator{}
|
return &dataTreeNavigator{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dataTreeNavigator) DeeplyAssign(context Context, path []interface{}, rhsNode *yaml.Node) error {
|
func (d *dataTreeNavigator) DeeplyAssign(context Context, rhsCandidateNode *CandidateNode) error {
|
||||||
|
|
||||||
rhsCandidateNode := &CandidateNode{
|
|
||||||
Path: path,
|
|
||||||
Node: rhsNode,
|
|
||||||
}
|
|
||||||
|
|
||||||
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
assignmentOp := &Operation{OperationType: assignOpType, Preferences: assignPreferences{}}
|
||||||
|
|
||||||
@ -36,7 +30,7 @@ func (d *dataTreeNavigator) DeeplyAssign(context Context, path []interface{}, rh
|
|||||||
|
|
||||||
assignmentOpNode := &ExpressionNode{
|
assignmentOpNode := &ExpressionNode{
|
||||||
Operation: assignmentOp,
|
Operation: assignmentOp,
|
||||||
LHS: createTraversalTree(path, traversePreferences{}, false),
|
LHS: createTraversalTree(rhsCandidateNode.Path, traversePreferences{}, false),
|
||||||
RHS: &ExpressionNode{Operation: rhsOp},
|
RHS: &ExpressionNode{Operation: rhsOp},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type base64Padder struct {
|
type base64Padder struct {
|
||||||
@ -70,11 +68,5 @@ func (dec *base64Decoder) Decode() (*CandidateNode, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dec.readAnything = true
|
dec.readAnything = true
|
||||||
return &CandidateNode{
|
return createStringScalarNode(buf.String()), nil
|
||||||
Node: &yaml.Node{
|
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
Tag: "!!str",
|
|
||||||
Value: buf.String(),
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/dimchansky/utfbom"
|
"github.com/dimchansky/utfbom"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type csvObjectDecoder struct {
|
type csvObjectDecoder struct {
|
||||||
@ -28,7 +27,7 @@ func (dec *csvObjectDecoder) Init(reader io.Reader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *csvObjectDecoder) convertToYamlNode(content string) *yaml.Node {
|
func (dec *csvObjectDecoder) convertToNode(content string) *CandidateNode {
|
||||||
node, err := parseSnippet(content)
|
node, err := parseSnippet(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createScalarNode(content, content)
|
return createScalarNode(content, content)
|
||||||
@ -36,14 +35,14 @@ func (dec *csvObjectDecoder) convertToYamlNode(content string) *yaml.Node {
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *csvObjectDecoder) createObject(headerRow []string, contentRow []string) *yaml.Node {
|
func (dec *csvObjectDecoder) createObject(headerRow []string, contentRow []string) *CandidateNode {
|
||||||
objectNode := &yaml.Node{Kind: yaml.MappingNode, Tag: "!!map"}
|
objectNode := &CandidateNode{Kind: MappingNode, Tag: "!!map"}
|
||||||
|
|
||||||
for i, header := range headerRow {
|
for i, header := range headerRow {
|
||||||
objectNode.Content = append(
|
objectNode.Content = append(
|
||||||
objectNode.Content,
|
objectNode.Content,
|
||||||
createScalarNode(header, header),
|
createScalarNode(header, header),
|
||||||
dec.convertToYamlNode(contentRow[i]))
|
dec.convertToNode(contentRow[i]))
|
||||||
}
|
}
|
||||||
return objectNode
|
return objectNode
|
||||||
}
|
}
|
||||||
@ -58,7 +57,7 @@ func (dec *csvObjectDecoder) Decode() (*CandidateNode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rootArray := &yaml.Node{Kind: yaml.SequenceNode, Tag: "!!seq"}
|
rootArray := &CandidateNode{Kind: SequenceNode, Tag: "!!seq"}
|
||||||
|
|
||||||
contentRow, err := dec.reader.Read()
|
contentRow, err := dec.reader.Read()
|
||||||
|
|
||||||
@ -73,9 +72,7 @@ func (dec *csvObjectDecoder) Decode() (*CandidateNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: DocumentNode,
|
||||||
Kind: yaml.DocumentNode,
|
Content: []*CandidateNode{rootArray},
|
||||||
Content: []*yaml.Node{rootArray},
|
|
||||||
},
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/magiconair/properties"
|
"github.com/magiconair/properties"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type propertiesDecoder struct {
|
type propertiesDecoder struct {
|
||||||
@ -53,15 +52,13 @@ func (dec *propertiesDecoder) applyPropertyComments(context Context, path []inte
|
|||||||
|
|
||||||
rhsCandidateNode := &CandidateNode{
|
rhsCandidateNode := &CandidateNode{
|
||||||
Path: path,
|
Path: path,
|
||||||
Node: &yaml.Node{
|
|
||||||
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")),
|
||||||
Kind: yaml.ScalarNode,
|
Kind: ScalarNode,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rhsCandidateNode.Node.Tag = guessTagFromCustomType(rhsCandidateNode.Node)
|
rhsCandidateNode.Tag = rhsCandidateNode.guessTagFromCustomType()
|
||||||
|
|
||||||
rhsOp := &Operation{OperationType: referenceOpType, CandidateNode: rhsCandidateNode}
|
rhsOp := &Operation{OperationType: referenceOpType, CandidateNode: rhsCandidateNode}
|
||||||
|
|
||||||
@ -87,15 +84,11 @@ func (dec *propertiesDecoder) applyProperty(context Context, properties *propert
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rhsNode := &yaml.Node{
|
rhsNode := createStringScalarNode(value)
|
||||||
Value: value,
|
rhsNode.Tag = rhsNode.guessTagFromCustomType()
|
||||||
Tag: "!!str",
|
rhsNode.Path = path
|
||||||
Kind: yaml.ScalarNode,
|
|
||||||
}
|
|
||||||
|
|
||||||
rhsNode.Tag = guessTagFromCustomType(rhsNode)
|
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) {
|
||||||
@ -118,10 +111,8 @@ func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
|
|||||||
properties.DisableExpansion = true
|
properties.DisableExpansion = true
|
||||||
|
|
||||||
rootMap := &CandidateNode{
|
rootMap := &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: MappingNode,
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context := Context{}
|
context := Context{}
|
||||||
@ -136,10 +127,8 @@ func (dec *propertiesDecoder) Decode() (*CandidateNode, error) {
|
|||||||
dec.finished = true
|
dec.finished = true
|
||||||
|
|
||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: DocumentNode,
|
||||||
Kind: yaml.DocumentNode,
|
Content: []*CandidateNode{rootMap},
|
||||||
Content: []*yaml.Node{rootMap.Node},
|
|
||||||
},
|
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
toml "github.com/pelletier/go-toml/v2/unstable"
|
toml "github.com/pelletier/go-toml/v2/unstable"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type tomlDecoder struct {
|
type tomlDecoder struct {
|
||||||
@ -37,10 +36,9 @@ func (dec *tomlDecoder) Init(reader io.Reader) error {
|
|||||||
}
|
}
|
||||||
dec.parser.Reset(buf.Bytes())
|
dec.parser.Reset(buf.Bytes())
|
||||||
dec.rootMap = &CandidateNode{
|
dec.rootMap = &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: MappingNode,
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
}}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,10 +62,12 @@ 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, path, valueNode)
|
return dec.d.DeeplyAssign(context, valueNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode *toml.Node) (bool, error) {
|
func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode *toml.Node) (bool, error) {
|
||||||
@ -95,8 +95,8 @@ func (dec *tomlDecoder) decodeKeyValuesIntoMap(rootMap *CandidateNode, tomlNode
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := make([]*yaml.Node, 0)
|
content := make([]*CandidateNode, 0)
|
||||||
log.Debug("!! createInlineTableMap")
|
log.Debug("!! createInlineTableMap")
|
||||||
|
|
||||||
iterator := tomlNode.Children()
|
iterator := tomlNode.Children()
|
||||||
@ -107,28 +107,26 @@ func (dec *tomlDecoder) createInlineTableMap(tomlNode *toml.Node) (*yaml.Node, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
keyValues := &CandidateNode{
|
keyValues := &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: MappingNode,
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dec.processKeyValueIntoMap(keyValues, child); err != nil {
|
if err := dec.processKeyValueIntoMap(keyValues, child); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
content = append(content, keyValues.Node.Content...)
|
content = append(content, keyValues.Content...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &yaml.Node{
|
return &CandidateNode{
|
||||||
Kind: yaml.MappingNode,
|
Kind: MappingNode,
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
Content: content,
|
Content: content,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := make([]*yaml.Node, 0)
|
content := make([]*CandidateNode, 0)
|
||||||
iterator := tomlNode.Children()
|
iterator := tomlNode.Children()
|
||||||
for iterator.Next() {
|
for iterator.Next() {
|
||||||
child := iterator.Node()
|
child := iterator.Node()
|
||||||
@ -139,43 +137,43 @@ func (dec *tomlDecoder) createArray(tomlNode *toml.Node) (*yaml.Node, error) {
|
|||||||
content = append(content, yamlNode)
|
content = append(content, yamlNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &yaml.Node{
|
return &CandidateNode{
|
||||||
Kind: yaml.SequenceNode,
|
Kind: SequenceNode,
|
||||||
Tag: "!!seq",
|
Tag: "!!seq",
|
||||||
Content: content,
|
Content: content,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createStringScalar(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createStringScalar(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := string(tomlNode.Data)
|
content := string(tomlNode.Data)
|
||||||
return createScalarNode(content, content), nil
|
return createScalarNode(content, content), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createBoolScalar(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createBoolScalar(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := string(tomlNode.Data)
|
content := string(tomlNode.Data)
|
||||||
return createScalarNode(content == "true", content), nil
|
return createScalarNode(content == "true", content), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createIntegerScalar(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createIntegerScalar(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := string(tomlNode.Data)
|
content := string(tomlNode.Data)
|
||||||
_, num, err := parseInt64(content)
|
_, num, err := parseInt64(content)
|
||||||
return createScalarNode(num, content), err
|
return createScalarNode(num, content), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createDateTimeScalar(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createDateTimeScalar(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := string(tomlNode.Data)
|
content := string(tomlNode.Data)
|
||||||
val, err := parseDateTime(time.RFC3339, content)
|
val, err := parseDateTime(time.RFC3339, content)
|
||||||
return createScalarNode(val, content), err
|
return createScalarNode(val, content), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) createFloatScalar(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) createFloatScalar(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
content := string(tomlNode.Data)
|
content := string(tomlNode.Data)
|
||||||
num, err := strconv.ParseFloat(content, 64)
|
num, err := strconv.ParseFloat(content, 64)
|
||||||
return createScalarNode(num, content), err
|
return createScalarNode(num, content), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) decodeNode(tomlNode *toml.Node) (*yaml.Node, error) {
|
func (dec *tomlDecoder) decodeNode(tomlNode *toml.Node) (*CandidateNode, error) {
|
||||||
switch tomlNode.Kind {
|
switch tomlNode.Kind {
|
||||||
case toml.Key, toml.String:
|
case toml.Key, toml.String:
|
||||||
return dec.createStringScalar(tomlNode)
|
return dec.createStringScalar(tomlNode)
|
||||||
@ -241,15 +239,13 @@ func (dec *tomlDecoder) Decode() (*CandidateNode, error) {
|
|||||||
// must have finished
|
// must have finished
|
||||||
dec.finished = true
|
dec.finished = true
|
||||||
|
|
||||||
if len(dec.rootMap.Node.Content) == 0 {
|
if len(dec.rootMap.Content) == 0 {
|
||||||
return nil, io.EOF
|
return nil, io.EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
return &CandidateNode{
|
return &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: DocumentNode,
|
||||||
Kind: yaml.DocumentNode,
|
Content: []*CandidateNode{dec.rootMap},
|
||||||
Content: []*yaml.Node{dec.rootMap.Node},
|
|
||||||
},
|
|
||||||
}, deferredError
|
}, deferredError
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -259,9 +255,9 @@ func (dec *tomlDecoder) processTopLevelNode(currentNode *toml.Node) (bool, error
|
|||||||
var err error
|
var err error
|
||||||
log.Debug("!!!!!!!!!!!!Going to process %v state is current %v", currentNode.Kind, NodeToString(dec.rootMap))
|
log.Debug("!!!!!!!!!!!!Going to process %v state is current %v", currentNode.Kind, NodeToString(dec.rootMap))
|
||||||
if currentNode.Kind == toml.Table {
|
if currentNode.Kind == toml.Table {
|
||||||
runAgainstCurrentExp, err = dec.processTable((currentNode))
|
runAgainstCurrentExp, err = dec.processTable(currentNode)
|
||||||
} else if currentNode.Kind == toml.ArrayTable {
|
} else if currentNode.Kind == toml.ArrayTable {
|
||||||
runAgainstCurrentExp, err = dec.processArrayTable((currentNode))
|
runAgainstCurrentExp, err = dec.processArrayTable(currentNode)
|
||||||
} else {
|
} else {
|
||||||
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(dec.rootMap, currentNode)
|
runAgainstCurrentExp, err = dec.decodeKeyValuesIntoMap(dec.rootMap, currentNode)
|
||||||
}
|
}
|
||||||
@ -281,10 +277,9 @@ func (dec *tomlDecoder) processTable(currentNode *toml.Node) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: MappingNode,
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
},
|
Path: fullPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
tableValue := dec.parser.Expression()
|
tableValue := dec.parser.Expression()
|
||||||
@ -301,21 +296,19 @@ 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, fullPath, tableNodeValue.Node)
|
err = dec.d.DeeplyAssign(c, tableNodeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return runAgainstCurrentExp, nil
|
return runAgainstCurrentExp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode *yaml.Node) error {
|
func (dec *tomlDecoder) arrayAppend(context Context, path []interface{}, rhsNode *CandidateNode) error {
|
||||||
rhsCandidateNode := &CandidateNode{
|
rhsCandidateNode := &CandidateNode{
|
||||||
Path: path,
|
Path: path,
|
||||||
Node: &yaml.Node{
|
Kind: SequenceNode,
|
||||||
Kind: yaml.SequenceNode,
|
|
||||||
Tag: "!!seq",
|
Tag: "!!seq",
|
||||||
Content: []*yaml.Node{rhsNode},
|
Content: []*CandidateNode{rhsNode},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assignmentOp := &Operation{OperationType: addAssignOpType}
|
assignmentOp := &Operation{OperationType: addAssignOpType}
|
||||||
@ -346,10 +339,9 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tableNodeValue := &CandidateNode{
|
tableNodeValue := &CandidateNode{
|
||||||
Node: &yaml.Node{
|
Kind: MappingNode,
|
||||||
Kind: yaml.MappingNode,
|
|
||||||
Tag: "!!map",
|
Tag: "!!map",
|
||||||
},
|
Path: fullPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
tableValue := dec.parser.Expression()
|
tableValue := dec.parser.Expression()
|
||||||
@ -363,7 +355,7 @@ func (dec *tomlDecoder) processArrayTable(currentNode *toml.Node) (bool, error)
|
|||||||
c = c.SingleChildContext(dec.rootMap)
|
c = c.SingleChildContext(dec.rootMap)
|
||||||
|
|
||||||
// += function
|
// += function
|
||||||
err = dec.arrayAppend(c, fullPath, tableNodeValue.Node)
|
err = dec.arrayAppend(c, fullPath, tableNodeValue)
|
||||||
|
|
||||||
return runAgainstCurrentExp, err
|
return runAgainstCurrentExp, err
|
||||||
}
|
}
|
||||||
|
@ -130,44 +130,65 @@ func (dec *yamlDecoder) convertStyle(oStyle yaml.Style) Style {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *yamlDecoder) ConvertToCandidateNode(yamlNode *yaml.Node) *CandidateNode {
|
func (dec *yamlDecoder) ConvertToCandidateNode(parent *CandidateNode, path []interface{}, yamlNode *yaml.Node) *CandidateNode {
|
||||||
kids := make([]*CandidateNode, len(yamlNode.Content))
|
|
||||||
for i, v := range yamlNode.Content {
|
|
||||||
kids[i] = dec.ConvertToCandidateNode(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &CandidateNode{
|
candidateNode := &CandidateNode{
|
||||||
Kind: dec.convertKind(yamlNode.Kind),
|
Kind: dec.convertKind(yamlNode.Kind),
|
||||||
Style: dec.convertStyle(yamlNode.Style),
|
Style: dec.convertStyle(yamlNode.Style),
|
||||||
|
|
||||||
Tag: yamlNode.Tag,
|
Tag: yamlNode.Tag,
|
||||||
Value: yamlNode.Value,
|
Value: yamlNode.Value,
|
||||||
Anchor: yamlNode.Anchor,
|
Anchor: yamlNode.Anchor,
|
||||||
Alias: dec.ConvertToCandidateNode(yamlNode.Alias),
|
|
||||||
Content: kids,
|
// not sure on this - check
|
||||||
|
Alias: dec.ConvertToCandidateNode(parent, path, yamlNode.Alias),
|
||||||
|
|
||||||
HeadComment: yamlNode.HeadComment,
|
HeadComment: yamlNode.HeadComment,
|
||||||
LineComment: yamlNode.LineComment,
|
LineComment: yamlNode.LineComment,
|
||||||
FootComment: yamlNode.FootComment,
|
FootComment: yamlNode.FootComment,
|
||||||
|
Path: path,
|
||||||
|
|
||||||
// Parent: yamlNode.Parent,
|
Parent: parent,
|
||||||
// Key: yamlNode.Key,
|
|
||||||
|
|
||||||
// LeadingContent: yamlNode.LeadingContent,
|
Document: parent.Document,
|
||||||
// TrailingContent: yamlNode.TrailingContent,
|
Filename: parent.Filename,
|
||||||
|
|
||||||
// Path: yamlNode.Path,
|
|
||||||
// Document: yamlNode.Document,
|
|
||||||
// Filename: yamlNode.Filename,
|
|
||||||
|
|
||||||
Line: yamlNode.Line,
|
Line: yamlNode.Line,
|
||||||
Column: yamlNode.Column,
|
Column: yamlNode.Column,
|
||||||
|
|
||||||
// FileIndex: yamlNode.FileIndex,
|
FileIndex: parent.FileIndex,
|
||||||
// EvaluateTogether: yamlNode.EvaluateTogether,
|
|
||||||
// IsMapKey: yamlNode.IsMapKey,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kids := make([]*CandidateNode, len(yamlNode.Content))
|
||||||
|
|
||||||
|
if yamlNode.Kind == yaml.MappingNode {
|
||||||
|
// children are key, values
|
||||||
|
for i := 0; i < len(yamlNode.Content); i = i + 2 {
|
||||||
|
key := yamlNode.Content[i]
|
||||||
|
value := yamlNode.Content[i+1]
|
||||||
|
|
||||||
|
childPath := parent.createChildPath(key.Value)
|
||||||
|
keyNode := dec.ConvertToCandidateNode(parent, childPath, key)
|
||||||
|
keyNode.IsMapKey = true
|
||||||
|
|
||||||
|
valueNode := dec.ConvertToCandidateNode(parent, childPath, value)
|
||||||
|
valueNode.Key = keyNode
|
||||||
|
|
||||||
|
kids[i] = keyNode
|
||||||
|
kids[i+1] = valueNode
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// its just an normal array
|
||||||
|
for i, v := range yamlNode.Content {
|
||||||
|
childPath := parent.createChildPath(i)
|
||||||
|
kids[i] = dec.ConvertToCandidateNode(parent, childPath, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
candidateNode.Content = kids
|
||||||
|
|
||||||
|
return candidateNode
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
|
func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
|
||||||
@ -190,7 +211,7 @@ func (dec *yamlDecoder) Decode() (*CandidateNode, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
candidateNode := dec.ConvertToCandidateNode(&dataBucket)
|
candidateNode := dec.ConvertToCandidateNode(&CandidateNode{}, make([]interface{}, 0), &dataBucket)
|
||||||
|
|
||||||
if dec.leadingContent != "" {
|
if dec.leadingContent != "" {
|
||||||
candidateNode.LeadingContent = dec.leadingContent
|
candidateNode.LeadingContent = dec.leadingContent
|
||||||
|
@ -258,10 +258,10 @@ func guessTagFromCustomType(node *yaml.Node) string {
|
|||||||
return guessedTag
|
return guessedTag
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSnippet(value string) (*yaml.Node, error) {
|
func parseSnippet(value string) (*CandidateNode, error) {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return &yaml.Node{
|
return &CandidateNode{
|
||||||
Kind: yaml.ScalarNode,
|
Kind: ScalarNode,
|
||||||
Tag: "!!null",
|
Tag: "!!null",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -274,10 +274,10 @@ func parseSnippet(value string) (*yaml.Node, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(parsedNode.Node.Content) == 0 {
|
if len(parsedNode.Content) == 0 {
|
||||||
return nil, fmt.Errorf("bad data")
|
return nil, fmt.Errorf("bad data")
|
||||||
}
|
}
|
||||||
result := unwrapDoc(parsedNode.Node)
|
result := parsedNode.unwrapDocument()
|
||||||
result.Line = 0
|
result.Line = 0
|
||||||
result.Column = 0
|
result.Column = 0
|
||||||
return result, err
|
return result, err
|
||||||
@ -382,13 +382,6 @@ func parseInt(numberString string) (int, error) {
|
|||||||
return int(parsed), err
|
return int(parsed), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createStringScalarNode(stringValue string) *yaml.Node {
|
|
||||||
var node = &yaml.Node{Kind: yaml.ScalarNode}
|
|
||||||
node.Value = stringValue
|
|
||||||
node.Tag = "!!str"
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
func headAndLineComment(node *yaml.Node) string {
|
func headAndLineComment(node *yaml.Node) string {
|
||||||
return headComment(node) + lineComment(node)
|
return headComment(node) + lineComment(node)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/elliotchance/orderedmap"
|
"github.com/elliotchance/orderedmap"
|
||||||
yaml "gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type traversePreferences struct {
|
type traversePreferences struct {
|
||||||
@ -17,7 +16,7 @@ type traversePreferences struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func splat(context Context, prefs traversePreferences) (Context, error) {
|
func splat(context Context, prefs traversePreferences) (Context, error) {
|
||||||
return traverseNodesWithArrayIndices(context, make([]*yaml.Node, 0), prefs)
|
return traverseNodesWithArrayIndices(context, make([]*CandidateNode, 0), prefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func traversePathOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
func traversePathOperator(d *dataTreeNavigator, context Context, expressionNode *ExpressionNode) (Context, error) {
|
||||||
@ -37,39 +36,38 @@ func traversePathOperator(d *dataTreeNavigator, context Context, expressionNode
|
|||||||
|
|
||||||
func traverse(context Context, matchingNode *CandidateNode, operation *Operation) (*list.List, error) {
|
func traverse(context Context, matchingNode *CandidateNode, operation *Operation) (*list.List, error) {
|
||||||
log.Debug("Traversing %v", NodeToString(matchingNode))
|
log.Debug("Traversing %v", NodeToString(matchingNode))
|
||||||
value := matchingNode.Node
|
|
||||||
|
|
||||||
if value.Tag == "!!null" && operation.Value != "[]" && !context.DontAutoCreate {
|
if matchingNode.Tag == "!!null" && operation.Value != "[]" && !context.DontAutoCreate {
|
||||||
log.Debugf("Guessing kind")
|
log.Debugf("Guessing kind")
|
||||||
// we must have added this automatically, lets guess what it should be now
|
// we must have added this automatically, lets guess what it should be now
|
||||||
switch operation.Value.(type) {
|
switch operation.Value.(type) {
|
||||||
case int, int64:
|
case int, int64:
|
||||||
log.Debugf("probably an array")
|
log.Debugf("probably an array")
|
||||||
value.Kind = yaml.SequenceNode
|
matchingNode.Kind = SequenceNode
|
||||||
default:
|
default:
|
||||||
log.Debugf("probably a map")
|
log.Debugf("probably a map")
|
||||||
value.Kind = yaml.MappingNode
|
matchingNode.Kind = MappingNode
|
||||||
}
|
}
|
||||||
value.Tag = ""
|
matchingNode.Tag = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
switch value.Kind {
|
switch matchingNode.Kind {
|
||||||
case yaml.MappingNode:
|
case MappingNode:
|
||||||
log.Debug("its a map with %v entries", len(value.Content)/2)
|
log.Debug("its a map with %v entries", len(matchingNode.Content)/2)
|
||||||
return traverseMap(context, matchingNode, createStringScalarNode(operation.StringValue), operation.Preferences.(traversePreferences), false)
|
return traverseMap(context, matchingNode, createStringScalarNode(operation.StringValue), operation.Preferences.(traversePreferences), false)
|
||||||
|
|
||||||
case yaml.SequenceNode:
|
case SequenceNode:
|
||||||
log.Debug("its a sequence of %v things!", len(value.Content))
|
log.Debug("its a sequence of %v things!", len(matchingNode.Content))
|
||||||
return traverseArray(matchingNode, operation, operation.Preferences.(traversePreferences))
|
return traverseArray(matchingNode, operation, operation.Preferences.(traversePreferences))
|
||||||
|
|
||||||
case yaml.AliasNode:
|
case AliasNode:
|
||||||
log.Debug("its an alias!")
|
log.Debug("its an alias!")
|
||||||
matchingNode.Node = matchingNode.Node.Alias
|
matchingNode = matchingNode.Alias
|
||||||
return traverse(context, matchingNode, operation)
|
return traverse(context, matchingNode, operation)
|
||||||
case yaml.DocumentNode:
|
case DocumentNode:
|
||||||
log.Debug("digging into doc node")
|
log.Debug("digging into doc node")
|
||||||
|
|
||||||
return traverse(context, matchingNode.CreateChildInMap(nil, matchingNode.Node.Content[0]), operation)
|
return traverse(context, matchingNode.Content[0], operation)
|
||||||
default:
|
default:
|
||||||
return list.New(), nil
|
return list.New(), nil
|
||||||
}
|
}
|
||||||
@ -103,7 +101,7 @@ func traverseArrayOperator(d *dataTreeNavigator, context Context, expressionNode
|
|||||||
if expressionNode.Operation.Preferences != nil {
|
if expressionNode.Operation.Preferences != nil {
|
||||||
prefs = expressionNode.Operation.Preferences.(traversePreferences)
|
prefs = expressionNode.Operation.Preferences.(traversePreferences)
|
||||||
}
|
}
|
||||||
var indicesToTraverse = rhs.MatchingNodes.Front().Value.(*CandidateNode).Node.Content
|
var indicesToTraverse = rhs.MatchingNodes.Front().Value.(*CandidateNode).Content
|
||||||
|
|
||||||
log.Debugf("indicesToTraverse %v", len(indicesToTraverse))
|
log.Debugf("indicesToTraverse %v", len(indicesToTraverse))
|
||||||
|
|
||||||
@ -115,7 +113,7 @@ func traverseArrayOperator(d *dataTreeNavigator, context Context, expressionNode
|
|||||||
return context.ChildContext(result.MatchingNodes), nil
|
return context.ChildContext(result.MatchingNodes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseNodesWithArrayIndices(context Context, indicesToTraverse []*yaml.Node, prefs traversePreferences) (Context, error) {
|
func traverseNodesWithArrayIndices(context Context, indicesToTraverse []*CandidateNode, prefs traversePreferences) (Context, error) {
|
||||||
var matchingNodeMap = list.New()
|
var matchingNodeMap = list.New()
|
||||||
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
|
||||||
candidate := el.Value.(*CandidateNode)
|
candidate := el.Value.(*CandidateNode)
|
||||||
@ -129,34 +127,33 @@ func traverseNodesWithArrayIndices(context Context, indicesToTraverse []*yaml.No
|
|||||||
return context.ChildContext(matchingNodeMap), nil
|
return context.ChildContext(matchingNodeMap), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseArrayIndices(context Context, matchingNode *CandidateNode, indicesToTraverse []*yaml.Node, prefs traversePreferences) (*list.List, error) { // call this if doc / alias like the other traverse
|
func traverseArrayIndices(context Context, matchingNode *CandidateNode, indicesToTraverse []*CandidateNode, prefs traversePreferences) (*list.List, error) { // call this if doc / alias like the other traverse
|
||||||
node := matchingNode.Node
|
if matchingNode.Tag == "!!null" {
|
||||||
if node.Tag == "!!null" {
|
|
||||||
log.Debugf("OperatorArrayTraverse got a null - turning it into an empty array")
|
log.Debugf("OperatorArrayTraverse got a null - turning it into an empty array")
|
||||||
// auto vivification
|
// auto vivification
|
||||||
node.Tag = ""
|
matchingNode.Tag = ""
|
||||||
node.Kind = yaml.SequenceNode
|
matchingNode.Kind = SequenceNode
|
||||||
//check that the indices are numeric, if not, then we should create an object
|
//check that the indices are numeric, if not, then we should create an object
|
||||||
if len(indicesToTraverse) != 0 && indicesToTraverse[0].Tag != "!!int" {
|
if len(indicesToTraverse) != 0 && indicesToTraverse[0].Tag != "!!int" {
|
||||||
node.Kind = yaml.MappingNode
|
matchingNode.Kind = MappingNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Kind == yaml.AliasNode {
|
if matchingNode.Kind == AliasNode {
|
||||||
matchingNode.Node = node.Alias
|
matchingNode = matchingNode.Alias
|
||||||
return traverseArrayIndices(context, matchingNode, indicesToTraverse, prefs)
|
return traverseArrayIndices(context, matchingNode, indicesToTraverse, prefs)
|
||||||
} else if node.Kind == yaml.SequenceNode {
|
} else if matchingNode.Kind == SequenceNode {
|
||||||
return traverseArrayWithIndices(matchingNode, indicesToTraverse, prefs)
|
return traverseArrayWithIndices(matchingNode, indicesToTraverse, prefs)
|
||||||
} else if node.Kind == yaml.MappingNode {
|
} else if matchingNode.Kind == MappingNode {
|
||||||
return traverseMapWithIndices(context, matchingNode, indicesToTraverse, prefs)
|
return traverseMapWithIndices(context, matchingNode, indicesToTraverse, prefs)
|
||||||
} else if node.Kind == yaml.DocumentNode {
|
} else if matchingNode.Kind == DocumentNode {
|
||||||
return traverseArrayIndices(context, matchingNode.CreateChildInMap(nil, matchingNode.Node.Content[0]), indicesToTraverse, prefs)
|
return traverseArrayIndices(context, matchingNode.Content[0], indicesToTraverse, prefs)
|
||||||
}
|
}
|
||||||
log.Debugf("OperatorArrayTraverse skipping %v as its a %v", matchingNode, node.Tag)
|
log.Debugf("OperatorArrayTraverse skipping %v as its a %v", matchingNode, matchingNode.Tag)
|
||||||
return list.New(), nil
|
return list.New(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseMapWithIndices(context Context, candidate *CandidateNode, indices []*yaml.Node, prefs traversePreferences) (*list.List, error) {
|
func traverseMapWithIndices(context Context, candidate *CandidateNode, indices []*CandidateNode, prefs traversePreferences) (*list.List, error) {
|
||||||
if len(indices) == 0 {
|
if len(indices) == 0 {
|
||||||
return traverseMap(context, candidate, createStringScalarNode(""), prefs, true)
|
return traverseMap(context, candidate, createStringScalarNode(""), prefs, true)
|
||||||
}
|
}
|
||||||
@ -175,15 +172,15 @@ func traverseMapWithIndices(context Context, candidate *CandidateNode, indices [
|
|||||||
return matchingNodeMap, nil
|
return matchingNodeMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node, prefs traversePreferences) (*list.List, error) {
|
func traverseArrayWithIndices(candidate *CandidateNode, indices []*CandidateNode, prefs traversePreferences) (*list.List, error) {
|
||||||
log.Debug("traverseArrayWithIndices")
|
log.Debug("traverseArrayWithIndices")
|
||||||
var newMatches = list.New()
|
var newMatches = list.New()
|
||||||
node := unwrapDoc(candidate.Node)
|
node := candidate.unwrapDocument()
|
||||||
if len(indices) == 0 {
|
if len(indices) == 0 {
|
||||||
log.Debug("splatting")
|
log.Debug("splatting")
|
||||||
var index int
|
var index int
|
||||||
for index = 0; index < len(node.Content); index = index + 1 {
|
for index = 0; index < len(node.Content); index = index + 1 {
|
||||||
newMatches.PushBack(candidate.CreateChildInArray(index, node.Content[index]))
|
newMatches.PushBack(node.Content[index])
|
||||||
}
|
}
|
||||||
return newMatches, nil
|
return newMatches, nil
|
||||||
|
|
||||||
@ -206,7 +203,7 @@ func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node, pr
|
|||||||
node.Style = 0
|
node.Style = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Content = append(node.Content, &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode, Value: "null"})
|
node.Content = append(node.Content, &CandidateNode{Tag: "!!null", Kind: ScalarNode, Value: "null"})
|
||||||
contentLength = len(node.Content)
|
contentLength = len(node.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,16 +215,16 @@ func traverseArrayWithIndices(candidate *CandidateNode, indices []*yaml.Node, pr
|
|||||||
return nil, fmt.Errorf("index [%v] out of range, array size is %v", index, contentLength)
|
return nil, fmt.Errorf("index [%v] out of range, array size is %v", index, contentLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
newMatches.PushBack(candidate.CreateChildInArray(index, node.Content[indexToUse]))
|
newMatches.PushBack(node.Content[indexToUse])
|
||||||
}
|
}
|
||||||
return newMatches, nil
|
return newMatches, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func keyMatches(key *yaml.Node, wantedKey string) bool {
|
func keyMatches(key *CandidateNode, wantedKey string) bool {
|
||||||
return matchKey(key.Value, wantedKey)
|
return matchKey(key.Value, wantedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseMap(context Context, matchingNode *CandidateNode, keyNode *yaml.Node, prefs traversePreferences, splat bool) (*list.List, error) {
|
func traverseMap(context Context, matchingNode *CandidateNode, keyNode *CandidateNode, prefs traversePreferences, splat bool) (*list.List, error) {
|
||||||
var newMatches = orderedmap.NewOrderedMap()
|
var newMatches = orderedmap.NewOrderedMap()
|
||||||
err := doTraverseMap(newMatches, matchingNode, keyNode.Value, prefs, splat)
|
err := doTraverseMap(newMatches, matchingNode, keyNode.Value, prefs, splat)
|
||||||
|
|
||||||
@ -238,26 +235,21 @@ func traverseMap(context Context, matchingNode *CandidateNode, keyNode *yaml.Nod
|
|||||||
if !splat && !prefs.DontAutoCreate && !context.DontAutoCreate && newMatches.Len() == 0 {
|
if !splat && !prefs.DontAutoCreate && !context.DontAutoCreate && newMatches.Len() == 0 {
|
||||||
log.Debugf("no matches, creating one")
|
log.Debugf("no matches, creating one")
|
||||||
//no matches, create one automagically
|
//no matches, create one automagically
|
||||||
valueNode := &yaml.Node{Tag: "!!null", Kind: yaml.ScalarNode, Value: "null"}
|
valueNode := &CandidateNode{Tag: "!!null", Kind: ScalarNode, Value: "null"}
|
||||||
|
|
||||||
node := matchingNode.Node
|
if len(matchingNode.Content) == 0 {
|
||||||
|
matchingNode.Style = 0
|
||||||
if len(node.Content) == 0 {
|
|
||||||
node.Style = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Content = append(node.Content, keyNode, valueNode)
|
matchingNode.Content = append(matchingNode.Content, keyNode, valueNode)
|
||||||
|
|
||||||
if prefs.IncludeMapKeys {
|
if prefs.IncludeMapKeys {
|
||||||
log.Debug("including key")
|
log.Debug("including key")
|
||||||
candidateNode := matchingNode.CreateChildInMap(keyNode, keyNode)
|
newMatches.Set(keyNode.GetKey(), keyNode)
|
||||||
candidateNode.IsMapKey = true
|
|
||||||
newMatches.Set(fmt.Sprintf("keyOf-%v", candidateNode.GetKey()), candidateNode)
|
|
||||||
}
|
}
|
||||||
if !prefs.DontIncludeMapValues {
|
if !prefs.DontIncludeMapValues {
|
||||||
log.Debug("including value")
|
log.Debug("including value")
|
||||||
candidateNode := matchingNode.CreateChildInMap(keyNode, valueNode)
|
newMatches.Set(valueNode.GetKey(), valueNode)
|
||||||
newMatches.Set(candidateNode.GetKey(), candidateNode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,14 +262,12 @@ func traverseMap(context Context, matchingNode *CandidateNode, keyNode *yaml.Nod
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTraverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode, wantedKey string, prefs traversePreferences, splat bool) error {
|
func doTraverseMap(newMatches *orderedmap.OrderedMap, node *CandidateNode, wantedKey string, prefs traversePreferences, splat bool) error {
|
||||||
// value.Content is a concatenated array of key, value,
|
// value.Content is a concatenated array of key, value,
|
||||||
// so keys are in the even indices, values in odd.
|
// so keys are in the even indices, values in odd.
|
||||||
// merge aliases are defined first, but we only want to traverse them
|
// merge aliases are defined first, but we only want to traverse them
|
||||||
// if we don't find a match directly on this node first.
|
// if we don't find a match directly on this node first.
|
||||||
|
|
||||||
node := candidate.Node
|
|
||||||
|
|
||||||
var contents = node.Content
|
var contents = node.Content
|
||||||
for index := 0; index < len(contents); index = index + 2 {
|
for index := 0; index < len(contents); index = index + 2 {
|
||||||
key := contents[index]
|
key := contents[index]
|
||||||
@ -287,7 +277,7 @@ func doTraverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode,
|
|||||||
//skip the 'merge' tag, find a direct match first
|
//skip the 'merge' tag, find a direct match first
|
||||||
if key.Tag == "!!merge" && !prefs.DontFollowAlias {
|
if key.Tag == "!!merge" && !prefs.DontFollowAlias {
|
||||||
log.Debug("Merge anchor")
|
log.Debug("Merge anchor")
|
||||||
err := traverseMergeAnchor(newMatches, candidate, value, wantedKey, prefs, splat)
|
err := traverseMergeAnchor(newMatches, node, value, wantedKey, prefs, splat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -295,14 +285,11 @@ func doTraverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode,
|
|||||||
log.Debug("MATCHED")
|
log.Debug("MATCHED")
|
||||||
if prefs.IncludeMapKeys {
|
if prefs.IncludeMapKeys {
|
||||||
log.Debug("including key")
|
log.Debug("including key")
|
||||||
candidateNode := candidate.CreateChildInMap(key, key)
|
newMatches.Set(key.GetKey(), key)
|
||||||
candidateNode.IsMapKey = true
|
|
||||||
newMatches.Set(fmt.Sprintf("keyOf-%v", candidateNode.GetKey()), candidateNode)
|
|
||||||
}
|
}
|
||||||
if !prefs.DontIncludeMapValues {
|
if !prefs.DontIncludeMapValues {
|
||||||
log.Debug("including value")
|
log.Debug("including value")
|
||||||
candidateNode := candidate.CreateChildInMap(key, value)
|
newMatches.Set(value.GetKey(), value)
|
||||||
newMatches.Set(candidateNode.GetKey(), candidateNode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,15 +297,15 @@ func doTraverseMap(newMatches *orderedmap.OrderedMap, candidate *CandidateNode,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func traverseMergeAnchor(newMatches *orderedmap.OrderedMap, originalCandidate *CandidateNode, value *yaml.Node, wantedKey string, prefs traversePreferences, splat bool) error {
|
func traverseMergeAnchor(newMatches *orderedmap.OrderedMap, originalCandidate *CandidateNode, value *CandidateNode, wantedKey string, prefs traversePreferences, splat bool) error {
|
||||||
switch value.Kind {
|
switch value.Kind {
|
||||||
case yaml.AliasNode:
|
case AliasNode:
|
||||||
if value.Alias.Kind != yaml.MappingNode {
|
if value.Alias.Kind != MappingNode {
|
||||||
return fmt.Errorf("can only use merge anchors with maps (!!map), but got %v", value.Alias.Tag)
|
return fmt.Errorf("can only use merge anchors with maps (!!map), but got %v", value.Alias.Tag)
|
||||||
}
|
}
|
||||||
candidateNode := originalCandidate.CreateReplacement(value.Alias)
|
// candidateNode := originalCandidate.CreateReplacement(value.Alias)
|
||||||
return doTraverseMap(newMatches, candidateNode, wantedKey, prefs, splat)
|
return doTraverseMap(newMatches, value.Alias, wantedKey, prefs, splat)
|
||||||
case yaml.SequenceNode:
|
case SequenceNode:
|
||||||
for _, childValue := range value.Content {
|
for _, childValue := range value.Content {
|
||||||
err := traverseMergeAnchor(newMatches, originalCandidate, childValue, wantedKey, prefs, splat)
|
err := traverseMergeAnchor(newMatches, originalCandidate, childValue, wantedKey, prefs, splat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -331,6 +318,6 @@ func traverseMergeAnchor(newMatches *orderedmap.OrderedMap, originalCandidate *C
|
|||||||
|
|
||||||
func traverseArray(candidate *CandidateNode, operation *Operation, prefs traversePreferences) (*list.List, error) {
|
func traverseArray(candidate *CandidateNode, operation *Operation, prefs traversePreferences) (*list.List, error) {
|
||||||
log.Debug("operation Value %v", operation.Value)
|
log.Debug("operation Value %v", operation.Value)
|
||||||
indices := []*yaml.Node{{Value: operation.StringValue}}
|
indices := []*CandidateNode{{Value: operation.StringValue}}
|
||||||
return traverseArrayWithIndices(candidate, indices, prefs)
|
return traverseArrayWithIndices(candidate, indices, prefs)
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,30 @@ var tomlScenarios = []formatScenario{
|
|||||||
expected: "person:\n name: hello\n address: 12 cat st\n",
|
expected: "person:\n name: hello\n address: 12 cat st\n",
|
||||||
scenarioType: "decode",
|
scenarioType: "decode",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Parse: include key information",
|
||||||
|
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
|
||||||
|
expression: ".person.name | key",
|
||||||
|
expected: "name\n",
|
||||||
|
scenarioType: "roundtrip",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Parse: include parent information",
|
||||||
|
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
|
||||||
|
expression: ".person.name | parent",
|
||||||
|
expected: "person\n",
|
||||||
|
scenarioType: "decode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
skipDoc: true,
|
||||||
|
description: "Parse: include path information",
|
||||||
|
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
|
||||||
|
expression: ".person.name | path",
|
||||||
|
expected: "- person\n- name\n",
|
||||||
|
scenarioType: "decode",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "Encode: Scalar",
|
description: "Encode: Scalar",
|
||||||
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
|
input: "person.name = \"hello\"\nperson.address = \"12 cat st\"\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user