Handle simple aliases

This commit is contained in:
Mike Farah 2019-12-16 20:38:55 +11:00
parent d7392f7b58
commit 290579ac7f
4 changed files with 42 additions and 13 deletions

View File

@ -112,6 +112,15 @@ func TestReadCmd(t *testing.T) {
// test.AssertResult(t, "21\n", result.Output)
// }
func TestReadAnchorsCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "read examples/simple-anchor.yaml foobar.a")
if result.Error != nil {
t.Error(result.Error)
}
test.AssertResult(t, "1\n", result.Output)
}
func TestReadInvalidDocumentIndexCmd(t *testing.T) {
cmd := getRootCommand()
result := test.RunCmd(cmd, "read -df examples/sample.yaml b.c")

View File

@ -0,0 +1,4 @@
foo: &foo
a: 1
foobar: *foo

View File

@ -18,14 +18,16 @@ type DataNavigator interface {
}
type navigator struct {
log *logging.Logger
log *logging.Logger
followAliases bool
}
type VisitorFn func(*yaml.Node) error
func NewDataNavigator(l *logging.Logger) DataNavigator {
func NewDataNavigator(l *logging.Logger, followAliases bool) DataNavigator {
return &navigator{
log: l,
log: l,
followAliases: followAliases,
}
}
@ -147,6 +149,10 @@ func (n *navigator) GuessKind(tail []string, guess yaml.Kind) yaml.Kind {
if tail[0] == "*" && (guess == yaml.SequenceNode || guess == yaml.MappingNode) {
return guess
}
if guess == yaml.AliasNode {
n.log.Debug("guess was an alias, okey doke.")
return guess
}
return yaml.MappingNode
}
@ -172,6 +178,7 @@ func (n *navigator) DebugNode(value *yaml.Node) {
}
func (n *navigator) recurse(value *yaml.Node, head string, tail []string, visitor VisitorFn) error {
n.log.Debug("recursing, processing %v", head)
switch value.Kind {
case yaml.MappingNode:
n.log.Debug("its a map with %v entries", len(value.Content)/2)
@ -187,6 +194,13 @@ func (n *navigator) recurse(value *yaml.Node, head string, tail []string, visito
return n.appendArray(value, tail, visitor)
}
return n.recurseArray(value, head, tail, visitor)
case yaml.AliasNode:
n.log.Debug("its an alias, followAliases: %v", n.followAliases)
n.DebugNode(value.Alias)
if n.followAliases == true {
return n.recurse(value.Alias, head, tail, visitor)
}
return nil
default:
return nil
}
@ -237,7 +251,7 @@ func (n *navigator) visitMatchingEntries(contents []*yaml.Node, key string, visi
// so keys are in the even indexes, values in odd.
for index := 0; index < len(contents); index = index + 2 {
content := contents[index]
n.log.Debug("index %v, checking %v", index, content.Value)
n.log.Debug("index %v, checking %v", index, content.Value))
if n.matchesKey(key, content.Value) {
errorVisiting := visit(index)
if errorVisiting != nil {

View File

@ -28,37 +28,39 @@ type lib struct {
func NewYqLib(l *logging.Logger) YqLib {
return &lib{
navigator: NewDataNavigator(l),
parser: NewPathParser(),
log: l,
parser: NewPathParser(),
log: l,
}
}
func (l *lib) DebugNode(node *yaml.Node) {
l.navigator.DebugNode(node)
navigator := NewDataNavigator(l.log, false)
navigator.DebugNode(node)
}
func (l *lib) Get(rootNode *yaml.Node, path string) (*yaml.Node, error) {
var paths = l.parser.ParsePath(path)
return l.navigator.Get(rootNode, paths)
navigator := NewDataNavigator(l.log, true)
return navigator.Get(rootNode, paths)
}
func (l *lib) New(path string) yaml.Node {
var paths = l.parser.ParsePath(path)
newNode := yaml.Node{Kind: l.navigator.GuessKind(paths, 0)}
navigator := NewDataNavigator(l.log, false)
newNode := yaml.Node{Kind: navigator.GuessKind(paths, 0)}
return newNode
}
func (l *lib) Update(rootNode *yaml.Node, updateCommand UpdateCommand) error {
// later - support other command types
navigator := NewDataNavigator(l.log, false)
l.log.Debugf("%v to %v", updateCommand.Command, updateCommand.Path)
switch updateCommand.Command {
case "update":
var paths = l.parser.ParsePath(updateCommand.Path)
return l.navigator.Update(rootNode, paths, updateCommand.Value)
return navigator.Update(rootNode, paths, updateCommand.Value)
case "delete":
var paths = l.parser.ParsePath(updateCommand.Path)
return l.navigator.Delete(rootNode, paths)
return navigator.Delete(rootNode, paths)
default:
return fmt.Errorf("Unknown command %v", updateCommand.Command)
}