From 40b2db580e2db009f2486527e0c932258b47d282 Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Thu, 19 Dec 2024 09:38:15 +0100 Subject: [PATCH] Treat empty or all-comments yaml file as no-op when loading it --- go/yamlutil/yamlutil.go | 7 +++-- go/yamlutil/yamlutil_test.go | 56 ++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 go/yamlutil/yamlutil_test.go diff --git a/go/yamlutil/yamlutil.go b/go/yamlutil/yamlutil.go index 06cf7d4..c6bcd19 100644 --- a/go/yamlutil/yamlutil.go +++ b/go/yamlutil/yamlutil.go @@ -1,7 +1,9 @@ package yamlutil import ( + "errors" "fmt" + "io" "os" "gopkg.in/yaml.v3" @@ -10,14 +12,15 @@ import ( // LoadYamlFile reads the file at the given path and unmarshals it into the // given pointer. func LoadYamlFile(into any, path string) error { - file, err := os.Open(path) if err != nil { return fmt.Errorf("opening file: %w", err) } defer file.Close() - if err = yaml.NewDecoder(file).Decode(into); err != nil { + if err = yaml.NewDecoder(file).Decode(into); errors.Is(err, io.EOF) { + return nil + } else if err != nil { return fmt.Errorf("decoding yaml: %w", err) } diff --git a/go/yamlutil/yamlutil_test.go b/go/yamlutil/yamlutil_test.go new file mode 100644 index 0000000..a3f2f42 --- /dev/null +++ b/go/yamlutil/yamlutil_test.go @@ -0,0 +1,56 @@ +package yamlutil + +import ( + "os" + "path/filepath" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLoadYamlFile(t *testing.T) { + type structA struct { + A int + B string + } + + tests := []struct { + name string + body string + want any + }{ + { + name: "empty body", + body: "", + want: structA{}, + }, + { + name: "all comments", + body: `# foo + # bar`, + want: structA{}, + }, + { + name: "success", + body: "a: 1\nb: foo\n", + want: structA{A: 1, B: "foo"}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var ( + dir = t.TempDir() + path = filepath.Join(dir, "f.yaml") + intoV = reflect.New(reflect.TypeOf(test.want)) + into = intoV.Interface() + ) + + require.NoError(t, os.WriteFile(path, []byte(test.body), 0444)) + assert.NoError(t, LoadYamlFile(into, path)) + assert.Equal(t, test.want, intoV.Elem().Interface()) + }) + } +}