diff --git a/pkg/engine/funcs.go b/pkg/engine/funcs.go index ba842a51a..957c4af56 100644 --- a/pkg/engine/funcs.go +++ b/pkg/engine/funcs.go @@ -50,6 +50,7 @@ func funcMap() template.FuncMap { // Add some extra functionality extra := template.FuncMap{ "toToml": toTOML, + "mustToToml": mustToTOML, "fromToml": fromTOML, "toYaml": toYAML, "mustToYaml": mustToYAML, @@ -155,9 +156,23 @@ func fromYAMLArray(str string) []any { func toTOML(v any) string { b := bytes.NewBuffer(nil) e := toml.NewEncoder(b) - err := e.Encode(v) - if err != nil { - return err.Error() + if err := e.Encode(v); err != nil { + // Errors are intentionally swallowed in templates. + return "" + } + return b.String() +} + +// mustToTOML takes an interface, marshals it to toml, and returns a string. +// It will panic if there is an error. +// +// This is designed to be called from a template when you need to ensure that +// the output TOML is valid. +func mustToTOML(v any) string { + b := bytes.NewBuffer(nil) + e := toml.NewEncoder(b) + if err := e.Encode(v); err != nil { + panic(err) } return b.String() } diff --git a/pkg/engine/funcs_test.go b/pkg/engine/funcs_test.go index 48202454e..1fe290869 100644 --- a/pkg/engine/funcs_test.go +++ b/pkg/engine/funcs_test.go @@ -25,7 +25,6 @@ import ( ) func TestFuncs(t *testing.T) { - //TODO write tests for failure cases tests := []struct { tpl, expect string vars any @@ -136,10 +135,9 @@ keyInElement1 = "valueInElement1"`, assert.Equal(t, tt.expect, b.String(), tt.tpl) } - loopMap := map[string]any{ - "foo": "bar", + nonSerializable := map[string]any{ + "foo": struct{ Fn func() }{}, } - loopMap["loop"] = []any{loopMap} mustFuncsTests := []struct { tpl string @@ -147,18 +145,25 @@ keyInElement1 = "valueInElement1"`, vars any }{{ tpl: `{{ mustToYaml . }}`, - vars: loopMap, + vars: nonSerializable, }, { tpl: `{{ mustToJson . }}`, - vars: loopMap, + vars: nonSerializable, + }, { + tpl: `{{ mustToToml . }}`, + vars: nonSerializable, }, { tpl: `{{ toYaml . }}`, expect: "", // should return empty string and swallow error - vars: loopMap, + vars: nonSerializable, }, { tpl: `{{ toJson . }}`, expect: "", // should return empty string and swallow error - vars: loopMap, + vars: nonSerializable, + }, { + tpl: `{{ toToml . }}`, + expect: "", // should return empty string and swallow error + vars: nonSerializable, }, }