From daca3bc3d6251de917c1bf2a2e0da733be3188f5 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Wed, 28 Aug 2024 08:32:33 -0400 Subject: [PATCH] improve CRD template field insertion line targeting --- hack/copy-crds-to-chart/go.mod | 2 +- hack/copy-crds-to-chart/main.go | 34 +++++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/hack/copy-crds-to-chart/go.mod b/hack/copy-crds-to-chart/go.mod index c224f8f244..9756020463 100644 --- a/hack/copy-crds-to-chart/go.mod +++ b/hack/copy-crds-to-chart/go.mod @@ -1,3 +1,3 @@ module github.com/hashicorp/consul-k8s/hack/copy-crds-to-chart -go 1.20 +go 1.21 diff --git a/hack/copy-crds-to-chart/main.go b/hack/copy-crds-to-chart/main.go index 8f7953a446..f3f7483e42 100644 --- a/hack/copy-crds-to-chart/main.go +++ b/hack/copy-crds-to-chart/main.go @@ -79,12 +79,7 @@ func realMain(helmPath string) error { ` release: {{ .Release.Name }}`, ` component: crd`, } - var split int - if dir == "bases" { - split = 8 - } else { - split = 9 - } + split := findSplit(splitOnNewlines, []string{"metadata", "name"}) withLabels := append(splitOnNewlines[0:split], append(labelLines, splitOnNewlines[split:]...)...) contents = strings.Join(withLabels, "\n") @@ -110,6 +105,33 @@ func realMain(helmPath string) error { return nil } +// findSplit finds the line number immediately following the given yamlPath elements. +// It assumes the first match of each element is the correct one (i.e. it will not attempt +// further path traversals after a partial match). This is a quick and dirty substitute for +// YAML parsing so we can insert content after known fields. +func findSplit(lines []string, yamlPath []string) int { + yamlPathIdx := 0 + getIndent := func(line string) int { + return len(line) - len(strings.TrimLeft(line, " ")) + } + minIndent := getIndent(lines[0]) + for i, line := range lines { + if strings.Contains(line, yamlPath[yamlPathIdx]) && + strings.HasPrefix(line, strings.Repeat(" ", minIndent)) { + if yamlPathIdx < len(yamlPath)-1 { + yamlPathIdx++ + // Ensure we don't leave the current search path by increasing the + // minimum expected indent to match the next line. + minIndent = max(minIndent, getIndent(lines[i+1])) + } else { + // We found it! Return next line number. + return i + 1 + } + } + } + panic("could not find YAML field: " + strings.Join(yamlPath, ".")) +} + func printf(format string, args ...interface{}) { fmt.Println(fmt.Sprintf(format, args...)) }