From 2618d4142e5cb4d16f7ad6ab844f50c2c2a75827 Mon Sep 17 00:00:00 2001 From: Min Kyu Lee Date: Fri, 19 Jul 2019 23:04:00 -0400 Subject: [PATCH] feat(helm): 'helm lint' lints dependent charts Signed-off-by: Min Kyu Lee --- cmd/helm/lint.go | 58 ++++++++++++------- cmd/helm/lint_test.go | 19 ++++++ .../testcharts/invaliddepchart/Chart.yaml | 4 ++ .../charts/depchart/Chart.yaml | 1 + .../invaliddepchart/requirements.yaml | 4 ++ docs/helm/helm_lint.md | 4 +- 6 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 cmd/helm/testdata/testcharts/invaliddepchart/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/invaliddepchart/charts/depchart/Chart.yaml create mode 100644 cmd/helm/testdata/testcharts/invaliddepchart/requirements.yaml diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 710221bf5..faaf57d19 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -36,7 +36,7 @@ import ( var longLintHelp = ` This command takes a path to a chart and runs a series of tests to verify that -the chart is well-formed. +the chart and its dependent charts are well-formed. If the linter encounters things that will cause the chart to fail installation, it will emit [ERROR] messages. If it encounters issues that break with convention @@ -100,29 +100,32 @@ func (l *lintCmd) run() error { var total int var failures int for _, path := range l.paths { - if linter, err := lintChart(path, rvals, l.namespace, l.strict); err != nil { - fmt.Println("==> Skipping", path) - fmt.Println(err) - if err == errLintNoChart { - failures = failures + 1 - } - } else { - fmt.Println("==> Linting", path) - - if len(linter.Messages) == 0 { - fmt.Println("Lint OK") - } - - for _, msg := range linter.Messages { - fmt.Println(msg) - } - - total = total + 1 - if linter.HighestSeverity >= lowestTolerance { - failures = failures + 1 + chartPaths := getChartPaths(path) + for _, chartPath := range chartPaths { + if linter, err := lintChart(chartPath, rvals, l.namespace, l.strict); err != nil { + fmt.Println("==> Skipping", chartPath) + fmt.Println(err) + if err == errLintNoChart { + failures = failures + 1 + } + } else { + fmt.Println("==> Linting", chartPath) + + if len(linter.Messages) == 0 { + fmt.Println("Lint OK") + } + + for _, msg := range linter.Messages { + fmt.Println(msg) + } + + total = total + 1 + if linter.HighestSeverity >= lowestTolerance { + failures = failures + 1 + } } + fmt.Println("") } - fmt.Println("") } msg := fmt.Sprintf("%d chart(s) linted", total) @@ -135,6 +138,17 @@ func (l *lintCmd) run() error { return nil } +func getChartPaths(root string) []string { + charts := []string{root} + filepath.Walk(filepath.Join(root, "charts"), func(path string, info os.FileInfo, err error) error { + if info != nil && (info.Name() == "Chart.yaml" || strings.HasSuffix(path, ".tgz")) { + charts = append(charts, filepath.Dir(path)) + } + return nil + }) + return charts +} + func lintChart(path string, vals []byte, namespace string, strict bool) (support.Linter, error) { var chartPath string linter := support.Linter{} diff --git a/cmd/helm/lint_test.go b/cmd/helm/lint_test.go index 67775893b..d191142ce 100644 --- a/cmd/helm/lint_test.go +++ b/cmd/helm/lint_test.go @@ -17,6 +17,8 @@ limitations under the License. package main import ( + "io/ioutil" + "os" "testing" ) @@ -29,6 +31,7 @@ var ( invalidArchivedChartPath = "testdata/testcharts/invalidcompressedchart0.1.0.tgz" chartDirPath = "testdata/testcharts/decompressedchart/" chartMissingManifest = "testdata/testcharts/chart-missing-manifest" + invalidDepChart = "testdata/testcharts/invaliddepchart" ) func TestLintChart(t *testing.T) { @@ -52,3 +55,19 @@ func TestLintChart(t *testing.T) { t.Errorf("Expected a chart parsing error") } } + +func TestLintDependentCharts(t *testing.T) { + pwd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + if err := os.Chdir(invalidDepChart); err != nil { + t.Fatal(err) + } + defer os.Chdir(pwd) + + linter := newLintCmd(ioutil.Discard) + if err := linter.Execute(); err == nil { + t.Errorf("Expected a chart parsing error") + } +} diff --git a/cmd/helm/testdata/testcharts/invaliddepchart/Chart.yaml b/cmd/helm/testdata/testcharts/invaliddepchart/Chart.yaml new file mode 100644 index 000000000..753a500b8 --- /dev/null +++ b/cmd/helm/testdata/testcharts/invaliddepchart/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: invaliddepchart +version: 0.1.0 diff --git a/cmd/helm/testdata/testcharts/invaliddepchart/charts/depchart/Chart.yaml b/cmd/helm/testdata/testcharts/invaliddepchart/charts/depchart/Chart.yaml new file mode 100644 index 000000000..4e05159b0 --- /dev/null +++ b/cmd/helm/testdata/testcharts/invaliddepchart/charts/depchart/Chart.yaml @@ -0,0 +1 @@ +description: A Helm chart for Kubernetes diff --git a/cmd/helm/testdata/testcharts/invaliddepchart/requirements.yaml b/cmd/helm/testdata/testcharts/invaliddepchart/requirements.yaml new file mode 100644 index 000000000..758b516ee --- /dev/null +++ b/cmd/helm/testdata/testcharts/invaliddepchart/requirements.yaml @@ -0,0 +1,4 @@ +dependencies: + - name: depchart + version: 0.1.0 + repository: "https://example.com/charts" diff --git a/docs/helm/helm_lint.md b/docs/helm/helm_lint.md index e341975b7..7c6c298e6 100644 --- a/docs/helm/helm_lint.md +++ b/docs/helm/helm_lint.md @@ -6,7 +6,7 @@ Examines a chart for possible issues This command takes a path to a chart and runs a series of tests to verify that -the chart is well-formed. +the chart and its dependent charts are well-formed. If the linter encounters things that will cause the chart to fail installation, it will emit [ERROR] messages. If it encounters issues that break with convention @@ -45,4 +45,4 @@ helm lint [flags] PATH * [helm](helm.md) - The Helm package manager for Kubernetes. -###### Auto generated by spf13/cobra on 16-May-2019 +###### Auto generated by spf13/cobra on 19-Jul-2019