From fb6cd4aaab744cc713ef5a571434b07d8112b9c9 Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Thu, 14 Nov 2019 21:33:13 -0500 Subject: [PATCH] Return first non-empty YAML document when parsing YAML streams Signed-off-by: Dave Henderson --- data/data.go | 33 +++++++++++++++++++++++++++++++-- data/data_test.go | 23 +++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/data/data.go b/data/data.go index a401fb19f..d0c136bce 100644 --- a/data/data.go +++ b/data/data.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/csv" "encoding/json" + "io" "strings" "github.com/joho/godotenv" @@ -84,13 +85,41 @@ func JSONArray(in string) ([]interface{}, error) { // YAML - Unmarshal a YAML Object func YAML(in string) (map[string]interface{}, error) { obj := make(map[string]interface{}) - return unmarshalObj(obj, in, yaml.Unmarshal) + s := strings.NewReader(in) + d := yaml.NewDecoder(s) + for { + err := d.Decode(&obj) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + if obj != nil { + break + } + } + return obj, nil } // YAMLArray - Unmarshal a YAML Array func YAMLArray(in string) ([]interface{}, error) { obj := make([]interface{}, 1) - return unmarshalArray(obj, in, yaml.Unmarshal) + s := strings.NewReader(in) + d := yaml.NewDecoder(s) + for { + err := d.Decode(&obj) + if err == io.EOF { + break + } + if err != nil { + return nil, err + } + if obj != nil { + break + } + } + return obj, nil } // TOML - Unmarshal a TOML Object diff --git a/data/data_test.go b/data/data_test.go index 63c95a16d..3ecf02c57 100644 --- a/data/data_test.go +++ b/data/data_test.go @@ -33,6 +33,15 @@ func TestUnmarshalObj(t *testing.T) { bar: baz one: 1.0 true: true +`)) + test(YAML(`# this comment marks an empty (nil!) document +--- +# this one too, for good measure +--- +foo: + bar: baz +one: 1.0 +true: true `)) obj := make(map[string]interface{}) @@ -65,6 +74,20 @@ func TestUnmarshalArray(t *testing.T) { "42": 18 corge: "false": blah +`)) + test(YAMLArray(`--- +# blah blah blah ignore this! +--- +- foo +- bar +- baz: + qux: true + quux: + "42": 18 + corge: + "false": blah +--- +this shouldn't be reached `)) obj := make([]interface{}, 1)