Repository: helm/helm
Pull request #13576 (2024-12-28 05:15:15)

refactor: Consolidate lint package Run() functions
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Make sure to read the Contributing Guide before submitting your PR: https://github.com/helm/helm/blob/main/CONTRIBUTING.md
2. If this PR closes another issue, add 'closes #<issue number>' somewhere in the PR summary. GitHub will automatically close that issue when this PR gets merged. Alternatively, adding 'refs #<issue number>' will not close the issue, but help provide the reviewer more context.-->

**What this PR does / why we need it**:
Clean up / consolidate into a single `RunAll()` function the `lint` package functions:
```
All()
AllWithKubeVersion()
AllWithKubeVersionAndSchemaValidation()
```

**Special notes for your reviewer**:

**If applicable**:
- [ ] this PR contains user facing changes (the `docs needed` label should be applied if so)
- [ ] this PR contains unit tests
- [ ] this PR has been tested for backwards compatibility



Patch:
diff --git a/pkg/action/lint.go b/pkg/action/lint.go
index 4ba90b8c3..06fc48612 100644
--- a/pkg/action/lint.go
+++ b/pkg/action/lint.go
@@ -126,5 +126,11 @@ func lintChart(path string, vals map[string]interface{}, namespace string, kubeV
 		return linter, errors.Wrap(err, "unable to check Chart.yaml file in chart")
 	}
 
-	return lint.AllWithKubeVersionAndSchemaValidation(chartPath, vals, namespace, kubeVersion, skipSchemaValidation), nil
+	return lint.RunAll(
+		chartPath,
+		vals,
+		namespace,
+		lint.WithKubeVersion(kubeVersion),
+		lint.WithSkipSchemaValidation(skipSchemaValidation),
+	), nil
 }
diff --git a/pkg/lint/lint.go b/pkg/lint/lint.go
index de07115ce..70a49ee90 100644
--- a/pkg/lint/lint.go
+++ b/pkg/lint/lint.go
@@ -24,25 +24,42 @@ import (
 	"helm.sh/helm/v4/pkg/lint/support"
 )
 
-// All runs all the available linters on the given base directory.
-func All(basedir string, values map[string]interface{}, namespace string, _ bool) support.Linter {
-	return AllWithKubeVersion(basedir, values, namespace, nil)
+type linterOptions struct {
+	KubeVersion          *chartutil.KubeVersion
+	SkipSchemaValidation bool
 }
 
-// AllWithKubeVersion runs all the available linters on the given base directory, allowing to specify the kubernetes version.
-func AllWithKubeVersion(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion) support.Linter {
-	return AllWithKubeVersionAndSchemaValidation(basedir, values, namespace, kubeVersion, false)
+type LinterOption func(lo *linterOptions)
+
+func WithKubeVersion(kubeVersion *chartutil.KubeVersion) LinterOption {
+	return func(lo *linterOptions) {
+		lo.KubeVersion = kubeVersion
+	}
+}
+
+func WithSkipSchemaValidation(skipSchemaValidation bool) LinterOption {
+	return func(lo *linterOptions) {
+		lo.SkipSchemaValidation = skipSchemaValidation
+	}
 }
 
-// AllWithKubeVersionAndSchemaValidation runs all the available linters on the given base directory, allowing to specify the kubernetes version and if schema validation is enabled or not.
-func AllWithKubeVersionAndSchemaValidation(basedir string, values map[string]interface{}, namespace string, kubeVersion *chartutil.KubeVersion, skipSchemaValidation bool) support.Linter {
-	// Using abs path to get directory context
-	chartDir, _ := filepath.Abs(basedir)
-
-	linter := support.Linter{ChartDir: chartDir}
-	rules.Chartfile(&linter)
-	rules.ValuesWithOverrides(&linter, values)
-	rules.TemplatesWithSkipSchemaValidation(&linter, values, namespace, kubeVersion, skipSchemaValidation)
-	rules.Dependencies(&linter)
-	return linter
+func RunAll(baseDir string, values map[string]interface{}, namespace string, options ...LinterOption) support.Linter {
+
+	chartDir, _ := filepath.Abs(baseDir)
+
+	lo := linterOptions{}
+	for _, option := range options {
+		option(&lo)
+	}
+
+	result := support.Linter{
+		ChartDir: chartDir,
+	}
+
+	rules.Chartfile(&result)
+	rules.ValuesWithOverrides(&result, values)
+	rules.TemplatesWithSkipSchemaValidation(&result, values, namespace, lo.KubeVersion, lo.SkipSchemaValidation)
+	rules.Dependencies(&result)
+
+	return result
 }


Test patch:
diff --git a/pkg/lint/lint_test.go b/pkg/lint/lint_test.go
index a6d7707d5..9246b64f2 100644
--- a/pkg/lint/lint_test.go
+++ b/pkg/lint/lint_test.go
@@ -28,7 +28,6 @@ import (
 var values map[string]interface{}
 
 const namespace = "testNamespace"
-const strict = false
 
 const badChartDir = "rules/testdata/badchartfile"
 const badValuesFileDir = "rules/testdata/badvaluesfile"
@@ -38,7 +37,7 @@ const subChartValuesDir = "rules/testdata/withsubchart"
 const malformedTemplate = "rules/testdata/malformed-template"
 
 func TestBadChart(t *testing.T) {
-	m := All(badChartDir, values, namespace, strict).Messages
+	m := RunAll(badChartDir, values, namespace).Messages
 	if len(m) != 8 {
 		t.Errorf("Number of errors %v", len(m))
 		t.Errorf("All didn't fail with expected errors, got %#v", m)
@@ -82,7 +81,7 @@ func TestBadChart(t *testing.T) {
 }
 
 func TestInvalidYaml(t *testing.T) {
-	m := All(badYamlFileDir, values, namespace, strict).Messages
+	m := RunAll(badYamlFileDir, values, namespace).Messages
 	if len(m) != 1 {
 		t.Fatalf("All didn't fail with expected errors, got %#v", m)
 	}
@@ -92,7 +91,7 @@ func TestInvalidYaml(t *testing.T) {
 }
 
 func TestBadValues(t *testing.T) {
-	m := All(badValuesFileDir, values, namespace, strict).Messages
+	m := RunAll(badValuesFileDir, values, namespace).Messages
 	if len(m) < 1 {
 		t.Fatalf("All didn't fail with expected errors, got %#v", m)
 	}
@@ -102,7 +101,7 @@ func TestBadValues(t *testing.T) {
 }
 
 func TestGoodChart(t *testing.T) {
-	m := All(goodChartDir, values, namespace, strict).Messages
+	m := RunAll(goodChartDir, values, namespace).Messages
 	if len(m) != 0 {
 		t.Error("All returned linter messages when it shouldn't have")
 		for i, msg := range m {
@@ -126,7 +125,7 @@ func TestHelmCreateChart(t *testing.T) {
 
 	// Note: we test with strict=true here, even though others have
 	// strict = false.
-	m := All(createdChart, values, namespace, true).Messages
+	m := RunAll(createdChart, values, namespace, WithSkipSchemaValidation(true)).Messages
 	if ll := len(m); ll != 1 {
 		t.Errorf("All should have had exactly 1 error. Got %d", ll)
 		for i, msg := range m {
@@ -173,7 +172,7 @@ func TestHelmCreateChart_CheckDeprecatedWarnings(t *testing.T) {
 		},
 	}
 
-	linterRunDetails := All(createdChart, updatedValues, namespace, true)
+	linterRunDetails := RunAll(createdChart, updatedValues, namespace, WithSkipSchemaValidation(true))
 	for _, msg := range linterRunDetails.Messages {
 		if strings.HasPrefix(msg.Error(), "[WARNING]") &&
 			strings.Contains(msg.Error(), "deprecated") {
@@ -187,7 +186,7 @@ func TestHelmCreateChart_CheckDeprecatedWarnings(t *testing.T) {
 // lint ignores import-values
 // See https://github.com/helm/helm/issues/9658
 func TestSubChartValuesChart(t *testing.T) {
-	m := All(subChartValuesDir, values, namespace, strict).Messages
+	m := RunAll(subChartValuesDir, values, namespace).Messages
 	if len(m) != 0 {
 		t.Error("All returned linter messages when it shouldn't have")
 		for i, msg := range m {
@@ -203,7 +202,7 @@ func TestMalformedTemplate(t *testing.T) {
 	ch := make(chan int, 1)
 	var m []support.Message
 	go func() {
-		m = All(malformedTemplate, values, namespace, strict).Messages
+		m = RunAll(malformedTemplate, values, namespace).Messages
 		ch <- 1
 	}()
 	select {