diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb29e8..51f83f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Add support for TOML configuration files - Add support for HCL configuration files +- Add support for YAML configuration files - Use stdlib for tests instead of convey - Public functions now panic when the data to be marshaled or unmarshaled is not a pointer to a struct. These errors should be caught during deelopment (with diff --git a/adapters.go b/adapters.go index 439b7c9..de5bae6 100644 --- a/adapters.go +++ b/adapters.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/hcl/v2/hclsimple" "github.com/hashicorp/hcl/v2/hclwrite" "github.com/pelletier/go-toml/v2" + "gopkg.in/yaml.v3" ) type filetype int @@ -20,6 +21,7 @@ const ( typeJSON typeTOML typeHCL + typeYAML ) // getType returns the type of the config file. @@ -31,6 +33,9 @@ func getType(filename string) filetype { return typeTOML case strings.HasSuffix(filename, ".hcl"): return typeHCL + case strings.HasSuffix(filename, ".yml") || + strings.HasSuffix(filename, ".yaml"): + return typeYAML default: return typeInvalid } @@ -47,6 +52,8 @@ func unmarshal(filepath string, data []byte, v any) error { return unmarshalTOML(data, v) case typeHCL: return unmarshalHCL(filepath, data, v) + case typeYAML: + return unmarshalYAML(data, v) default: return ErrUnsupportedFileType } @@ -61,6 +68,8 @@ func marshal(ft filetype, v any) ([]byte, error) { return marshalTOML(v) case typeHCL: return marshalHCL(v) + case typeYAML: + return marshalYAML(v) default: return nil, ErrUnsupportedFileType } @@ -123,7 +132,7 @@ func unmarshalHCL(filepath string, data []byte, v any) error { } // marshalHCL marshals the given struct to bytes. -func marshalHCL(v any) (b []byte, err error) { //nolint:nonamedreturns // need named return to convert a panic to error +func marshalHCL(v any) ([]byte, error) { f := hclwrite.NewEmptyFile() gohcl.EncodeIntoBody(v, f.Body()) @@ -145,3 +154,23 @@ func hclFilterDiagnostics(diags hcl.Diagnostics) hcl.Diagnostics { return nil } + +// unmarshalYAML unmarshals the given data to the given struct. +func unmarshalYAML(data []byte, v any) error { + err := yaml.Unmarshal(data, v) + if err != nil { + return fmt.Errorf("cannot parse config file: %w", err) + } + + return nil +} + +// marshalYAML marshals the given struct to bytes. +func marshalYAML(v any) ([]byte, error) { + data, err := yaml.Marshal(v) + if err != nil { + return nil, fmt.Errorf("cannot generate config content: %w", err) + } + + return data, nil +} diff --git a/config_test.go b/config_test.go index d4d1a15..d302d3b 100644 --- a/config_test.go +++ b/config_test.go @@ -29,6 +29,12 @@ func TestHCLFiles(t *testing.T) { runTestSuite(t, "hcl") } +func TestYAMLFiles(t *testing.T) { + t.Parallel() + + runTestSuite(t, "yaml") +} + func TestUnknownFiles(t *testing.T) { t.Parallel() @@ -457,7 +463,7 @@ func testLoadAndUpdateFile(t *testing.T, ext string) { newContent, err := os.ReadFile(file) require.NoError(t, err) - assert.Contains(t, string(newContent), "Invariant") + assert.Contains(t, string(newContent), "nvariant") assert.True(t, updated) }) diff --git a/test_data/full.yaml b/test_data/full.yaml new file mode 100644 index 0000000..30d5fd3 --- /dev/null +++ b/test_data/full.yaml @@ -0,0 +1,3 @@ +string: default string +invariant: should not change +int: 1 diff --git a/test_data/invalid.yaml b/test_data/invalid.yaml new file mode 100644 index 0000000..0b9a56d --- /dev/null +++ b/test_data/invalid.yaml @@ -0,0 +1 @@ +String = not yaml diff --git a/test_data/part1.yaml b/test_data/part1.yaml new file mode 100644 index 0000000..070f4f4 --- /dev/null +++ b/test_data/part1.yaml @@ -0,0 +1 @@ +string: foo diff --git a/test_data/part2.yaml b/test_data/part2.yaml new file mode 100644 index 0000000..0e1ed1c --- /dev/null +++ b/test_data/part2.yaml @@ -0,0 +1 @@ +int: 42 diff --git a/test_data/same1.yaml b/test_data/same1.yaml new file mode 100644 index 0000000..070f4f4 --- /dev/null +++ b/test_data/same1.yaml @@ -0,0 +1 @@ +string: foo diff --git a/test_data/same2.yaml b/test_data/same2.yaml new file mode 100644 index 0000000..5606868 --- /dev/null +++ b/test_data/same2.yaml @@ -0,0 +1 @@ +string: bar diff --git a/test_data/unknown.yaml b/test_data/unknown.yaml new file mode 100644 index 0000000..9bd8a43 --- /dev/null +++ b/test_data/unknown.yaml @@ -0,0 +1,3 @@ +String: config string +Int: 42 +Unknown: "foo" diff --git a/test_data/valid.yaml b/test_data/valid.yaml new file mode 100644 index 0000000..f928b37 --- /dev/null +++ b/test_data/valid.yaml @@ -0,0 +1,2 @@ +string: config string +int: 42