From b6a3b5fa9399a81af7d373dbcfe63ff9270d02c0 Mon Sep 17 00:00:00 2001 From: Matt Butcher Date: Fri, 1 May 2020 18:16:15 -0600 Subject: [PATCH] feat: lint info on template spacing failure Signed-off-by: Matt Butcher --- pkg/lint/rules/template.go | 21 +++++++++++++++++++++ pkg/lint/rules/template_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/pkg/lint/rules/template.go b/pkg/lint/rules/template.go index 787c5b26a..778c616c0 100644 --- a/pkg/lint/rules/template.go +++ b/pkg/lint/rules/template.go @@ -106,6 +106,7 @@ func Templates(linter *support.Linter, values map[string]interface{}, namespace // chart is not compatible with v3 linter.RunLinterRule(support.WarningSev, path, validateNoCRDHooks(data)) linter.RunLinterRule(support.ErrorSev, path, validateNoReleaseTime(data)) + linter.RunLinterRule(support.InfoSev, path, validateWhitespaceAroundTemplateDirectives(string(data))) // We only apply the following lint rules to yaml files if filepath.Ext(fileName) != ".yaml" || filepath.Ext(fileName) == ".yml" { @@ -185,6 +186,26 @@ func validateNoReleaseTime(manifest []byte) error { return nil } +// TODO: I strongly suspect that there are better regexps than these two. +var ( + badTplStart = regexp.MustCompile(`{{-?[^-\s]+`) + badTplEnd = regexp.MustCompile(`[^\s-]+-?}}`) +) + +func validateWhitespaceAroundTemplateDirectives(template string) error { + badMatches := []string{} + if matches := badTplStart.FindAllString(template, 10); matches != nil { + badMatches = append(badMatches, fmt.Sprintf("\nbad start: %s", strings.Join(matches, "\n\t"))) + } + if matches := badTplEnd.FindAllString(template, 10); matches != nil { + badMatches = append(badMatches, fmt.Sprintf("\nbad end: %s", strings.Join(matches, "\n\t"))) + } + if len(badMatches) == 0 { + return nil + } + return fmt.Errorf("whitespace required between template markers and body: %s", strings.Join(badMatches, "\n")) +} + // K8sYamlStruct stubs a Kubernetes YAML file. // // DEPRECATED: In Helm 4, this will be made a private type, as it is for use only within diff --git a/pkg/lint/rules/template_test.go b/pkg/lint/rules/template_test.go index 991c6c2f6..ff2d174e6 100644 --- a/pkg/lint/rules/template_test.go +++ b/pkg/lint/rules/template_test.go @@ -226,3 +226,31 @@ func TestStrictTemplateParsingMapError(t *testing.T) { } } } + +func TestValidateWhitespaceAroundTemplateDirectives(t *testing.T) { + for example, success := range map[string]bool{ + "{{foo}}": false, + "{{-foo-}}": false, + "{{ foo-}}": false, + "{{ foo}}": false, + "{{-foo }}": false, + "{{foo }}": false, + "{{ foo }}": true, + "{{ default 2 .Values.foo }}": true, + "{{default 2 .Values.foo }}": false, + "{{ default 2 .Values.foo}}": false, + `{{ default "}" .Values.foo }}`: true, + `{{- foo }}`: true, + `{{ legal }}{{illegal }}`: false, + `{{ legal }}{{- legal -}}`: true, + "{{\nlegal\n}}": true, + } { + if err := validateWhitespaceAroundTemplateDirectives(example); (err == nil) != success { + st := "failure" + if success { + st = "success" + } + t.Errorf("Expected %s for %q", st, example) + } + } +}