From 81672d4efede601dd3b73ba863a0fe8424dac3a8 Mon Sep 17 00:00:00 2001 From: mfarah Date: Tue, 6 Oct 2015 10:01:33 +1100 Subject: [PATCH] Can now splat maps --- README.md | 22 ++++++++++++++++++++++ data_navigator.go | 17 +++++++++++++++++ data_navigator_test.go | 27 +++++++++++++++++++++++++++ sample2.yaml | 9 +++++++-- 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d53764..d93e7d0 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,26 @@ cat sample.yaml | yaml - b.c ``` will output the value of '2'. +### Splat +Given a sample.yaml file of: +```yaml +--- +bob: + item1: + cats: bananas + item2: + cats: apples +``` +then +```bash +yaml sample.yaml bob.*.cats +``` +will output +```yaml +- bananas +- apples +``` + ### Handling '.' in the yaml key Given a sample.yaml file of: ```yaml @@ -82,6 +102,8 @@ will output: - sam ``` + + ### Updating yaml Given a sample.yaml file of: ```yaml diff --git a/data_navigator.go b/data_navigator.go index 41e8edc..f82e71d 100644 --- a/data_navigator.go +++ b/data_navigator.go @@ -19,10 +19,27 @@ func write(context map[interface{}]interface{}, head string, tail []string, valu } func readMap(context map[interface{}]interface{}, head string, tail []string) interface{} { + if head == "*" { + return readMapSplat(context, tail) + } value := context[head] return calculateValue(value, tail) } +func readMapSplat(context map[interface{}]interface{}, tail []string) interface{} { + var newArray = make([]interface{}, len(context)) + var i = 0 + for _, value := range context { + if len(tail) > 0 { + newArray[i] = recurse(value, tail[0], tail[1:len(tail)]) + } else { + newArray[i] = value + } + i++ + } + return newArray +} + func recurse(value interface{}, head string, tail []string) interface{} { switch value.(type) { case []interface{}: diff --git a/data_navigator_test.go b/data_navigator_test.go index 40841a0..ca36215 100644 --- a/data_navigator_test.go +++ b/data_navigator_test.go @@ -4,6 +4,7 @@ import ( "fmt" "gopkg.in/yaml.v2" "os" + "sort" "testing" ) @@ -26,6 +27,32 @@ b: assertResult(t, 2, readMap(data, "b", []string{"c"})) } +func TestReadMap_splat(t *testing.T) { + var data = parseData(` +--- +mapSplat: + item1: things + item2: whatever +`) + assertResult(t, "[things whatever]", fmt.Sprintf("%v", readMap(data, "mapSplat", []string{"*"}))) +} + +func TestReadMap_deep_splat(t *testing.T) { + var data = parseData(` +--- +mapSplatDeep: + item1: + cats: bananas + item2: + cats: apples +`) + + var result = readMap(data, "mapSplatDeep", []string{"*", "cats"}).([]interface{}) + var actual = []string{result[0].(string), result[1].(string)} + sort.Strings(actual) + assertResult(t, "[apples bananas]", fmt.Sprintf("%v", actual)) +} + func TestReadMap_key_doesnt_exist(t *testing.T) { var data = parseData(` --- diff --git a/sample2.yaml b/sample2.yaml index 1d68a2f..fea95f2 100644 --- a/sample2.yaml +++ b/sample2.yaml @@ -1,4 +1,9 @@ a: Easy! as one two three b: - c: 3 - d: [3, 4] + c: things + d: whatever +things: + thing1: + cat: 'fred' + thing2: + cat: 'sam'