From b060911075950273c8d42c005dd5928d905c0ab0 Mon Sep 17 00:00:00 2001 From: Jesse Simpson Date: Sat, 6 Sep 2025 11:36:39 -0400 Subject: [PATCH] refactor: break out into functions and draft tests Signed-off-by: Jesse Simpson --- pkg/engine/engine.go | 61 +++++++++++++++++++++++++++++---------- pkg/engine/engine_test.go | 47 ++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 15 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index b42fa3219..a5532f73a 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -360,12 +360,56 @@ func parseTemplateExecErrorString(s string) (TraceableError, bool) { // Special case: "template: no template %q associated with template %q" // Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=191 - if strings.HasPrefix(remainder, "no template ") { - return TraceableError{message: s}, true + traceableError, done := parseTemplateNoTemplateError(s, remainder) + if done { + return traceableError, done } // Executing form: ": executing \"\" at <>: [ template:...]" // Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=141 + traceableError, done = parseTemplateExecutingAtErrorType(remainder) + if done { + return traceableError, done + } + + // Simple form: ": " + // Use LastIndex to avoid splitting colons within line:col info. + // Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=138 + traceableError, done = parseTemplateSimpleErrorString(remainder) + if done { + return traceableError, done + } + + return TraceableError{}, false +} + +// Special case: "template: no template %q associated with template %q" +// Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=191 +func parseTemplateNoTemplateError(s string, remainder string) (TraceableError, bool) { + if strings.HasPrefix(remainder, "no template ") { + return TraceableError{message: s}, true + } + return TraceableError{}, false +} + +// Simple form: ": " +// Use LastIndex to avoid splitting colons within line:col info. +// Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=138 +func parseTemplateSimpleErrorString(remainder string) (TraceableError, bool) { + if sep := strings.LastIndex(remainder, ": "); sep != -1 { + templateName := remainder[:sep] + errMsg := remainder[sep+2:] + if cut := strings.Index(errMsg, " template:"); cut != -1 { + errMsg = errMsg[:cut] + } + return TraceableError{location: templateName, message: errMsg}, true + } + return TraceableError{}, false +} + +// Executing form: ": executing \"\" at <>: [ template:...]" +// Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=141 +func parseTemplateExecutingAtErrorType(remainder string) (TraceableError, bool) { if idx := strings.Index(remainder, ": executing "); idx != -1 { templateName := remainder[:idx] after := remainder[idx+len(": executing "):] @@ -404,19 +448,6 @@ func parseTemplateExecErrorString(s string) (TraceableError, bool) { executedFunction: "executing \"" + functionName + "\" at <" + locationName + ">:", }, true } - - // Simple form: ": " - // Use LastIndex to avoid splitting colons within line:col info. - // Matches https://cs.opensource.google/go/go/+/refs/tags/go1.23.6:src/text/template/exec.go;l=138 - if sep := strings.LastIndex(remainder, ": "); sep != -1 { - templateName := remainder[:sep] - errMsg := remainder[sep+2:] - if cut := strings.Index(errMsg, " template:"); cut != -1 { - errMsg = errMsg[:cut] - } - return TraceableError{location: templateName, message: errMsg}, true - } - return TraceableError{}, false } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index f4228fbd7..3362fa37e 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -1428,3 +1428,50 @@ func TestRenderCustomTemplateFuncs(t *testing.T) { t.Errorf("Expected %q, got %q", expected, rendered) } } + +func TestTraceableError_SimpleForm(t *testing.T) { + testStrings := []string{ + "function_not_found/templates/secret.yaml: error calling include", + } + for _, errString := range testStrings { + trace, done := parseTemplateSimpleErrorString(errString) + if !done { + t.Errorf("Expected parse to pass but did not") + } + if trace.message != "error calling include" { + t.Errorf("Expected %q, got %q", errString, trace.message) + } + } +} +func TestTraceableError_ExecutingForm(t *testing.T) { + testStrings := [][]string{ + {"template: executing \"function_not_found/templates/secret.yaml\" at : ", "function_not_found/templates/secret.yaml"}, + {"template: executing \"name\" at : ", "name"}, + } + for _, errTuple := range testStrings { + errString := errTuple[0] + expectedLocation := errTuple[1] + trace, done := parseTemplateExecutingAtErrorType(errString) + if !done { + t.Errorf("Expected parse to pass but did not") + } + if trace.location != expectedLocation { + t.Errorf("Expected %q, got %q", expectedLocation, trace.location) + } + } +} + +func TestTraceableError_NoTemplateForm(t *testing.T) { + testStrings := []string{ + "no template \"common.names.get_name\" associated with template \"gotpl\"", + } + for _, errString := range testStrings { + trace, done := parseTemplateNoTemplateError(errString, "") + if !done { + t.Errorf("Expected parse to pass but did not") + } + if trace.message != errString { + t.Errorf("Expected %q, got %q", errString, trace.message) + } + } +}