From d41bd9aa5b5534c4f95e9838b546ec36224f24ab Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 20 Mar 2025 16:34:07 +0100 Subject: [PATCH] blueprintload: enable strict checking for toml Add strict checking for toml keys in blueprints. This allows us to error early if there are unknown keys in a toml blueprint and helps our users by spotting e.g. typos early. This is similar to https://github.com/osbuild/bootc-image-builder/pull/549 (thanks Ondrej!). --- internal/blueprintload/blueprintload.go | 5 ++++- internal/blueprintload/blueprintload_test.go | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/internal/blueprintload/blueprintload.go b/internal/blueprintload/blueprintload.go index e06135c..84be8bc 100644 --- a/internal/blueprintload/blueprintload.go +++ b/internal/blueprintload/blueprintload.go @@ -17,10 +17,13 @@ func decodeToml(r io.Reader, what string) (*blueprint.Blueprint, error) { dec := toml.NewDecoder(r) var conf blueprint.Blueprint - _, err := dec.Decode(&conf) + metadata, err := dec.Decode(&conf) if err != nil { return nil, fmt.Errorf("cannot decode %q: %w", what, err) } + if len(metadata.Undecoded()) > 0 { + return nil, fmt.Errorf("cannot decode %q: unknown keys found: %v", what, metadata.Undecoded()) + } return &conf, nil } diff --git a/internal/blueprintload/blueprintload_test.go b/internal/blueprintload/blueprintload_test.go index de7ad84..f3878cc 100644 --- a/internal/blueprintload/blueprintload_test.go +++ b/internal/blueprintload/blueprintload_test.go @@ -27,6 +27,17 @@ var testBlueprintTOML = ` name = "alice" ` +var testBlueprintJSONunknownKeys = ` +{ + "birds": {"name": "robin"} +} +` + +var testBlueprintTOMLunknownKeys = ` +[[birds]] +name = "robin" +` + var expectedBlueprint = &blueprint.Blueprint{ Customizations: &blueprint.Customizations{ User: []blueprint.UserCustomization{ @@ -55,9 +66,11 @@ func TestBlueprintLoadJSON(t *testing.T) { }{ {"bp.json", testBlueprintJSON, expectedBlueprint, ""}, {"bp.toml", testBlueprintTOML, expectedBlueprint, ""}, - {"bp.toml", "wrong-content", nil, `cannot decode .*/bp.toml": toml: `}, - {"bp.json", "wrong-content", nil, `cannot decode .*/bp.json": invalid `}, + {"bp.toml", "wrong-content", nil, `cannot decode ".*/bp.toml": toml: `}, + {"bp.json", "wrong-content", nil, `cannot decode ".*/bp.json": invalid `}, {"bp", "wrong-content", nil, `unsupported file extension for "/.*/bp"`}, + {"bp.toml", testBlueprintTOMLunknownKeys, nil, `cannot decode ".*/bp.toml": unknown keys found: \[birds birds.name\]`}, + {"bp.json", testBlueprintJSONunknownKeys, nil, `cannot decode ".*/bp.json": json: unknown field "birds"`}, } { blueprintPath := makeTestBlueprint(t, tc.fname, tc.content) bp, err := blueprintload.Load(blueprintPath)