diff --git a/cmd/helm/lint.go b/cmd/helm/lint.go index 0c259d987..999955594 100644 --- a/cmd/helm/lint.go +++ b/cmd/helm/lint.go @@ -18,6 +18,7 @@ package main import ( "fmt" + "helm.sh/helm/v3/pkg/lint/support" "io" "os" "path/filepath" @@ -58,6 +59,7 @@ func newLintCmd(out io.Writer) *cobra.Command { if len(args) > 0 { paths = args } + if kubeVersion != "" { parsedKubeVersion, err := chartutil.ParseKubeVersion(kubeVersion) if err != nil { @@ -65,6 +67,7 @@ func newLintCmd(out io.Writer) *cobra.Command { } client.KubeVersion = parsedKubeVersion } + if client.WithSubcharts { for _, p := range paths { filepath.Walk(filepath.Join(p, "charts"), func(path string, info os.FileInfo, _ error) error { @@ -79,40 +82,75 @@ func newLintCmd(out io.Writer) *cobra.Command { }) } } + client.Namespace = settings.Namespace() vals, err := valueOpts.MergeValues(getter.All(settings)) if err != nil { return err } + var ignorePatterns map[string][]string if lintIgnoreFile != "" { debug("\nUsing ignore file: %s\n", lintIgnoreFile) ignorePatterns, err = rules.ParseIgnoreFile(lintIgnoreFile) } + var message strings.Builder failed := 0 + errorsOrWarnings := 0 + for _, path := range paths { - fmt.Fprintf(&message, "==> Linting %s\n", path) result := client.Run([]string{path}, vals) result.Messages = rules.FilterIgnoredMessages(result.Messages, ignorePatterns) result.Errors = rules.FilterIgnoredErrors(result.Errors, ignorePatterns) - for _, msg := range result.Messages { - fmt.Fprintf(&message, "%s\n", msg) + + // If there is no errors/warnings and quiet flag is set + // go to the next chart + hasWarningsOrErrors := action.HasWarningsOrErrors(result) + if hasWarningsOrErrors { + errorsOrWarnings++ } - if len(result.Messages) != 0 { - failed++ + if client.Quiet && !hasWarningsOrErrors { + continue + } + + fmt.Fprintf(&message, "==> Linting %s\n", path) + + // All the Errors that are generated by a chart + // that failed a lint will be included in the + // results.Messages so we only need to print + // the Errors if there are no Messages. + if len(result.Messages) == 0 { for _, err := range result.Errors { - fmt.Fprintf(&message, "Error: %s\n", err) + fmt.Fprintf(&message, "Error %s\n", err) + } + } + + for _, msg := range result.Messages { + if !client.Quiet || msg.Severity > support.InfoSev { + fmt.Fprintf(&message, "%s\n", msg) } } + + if len(result.Errors) != 0 { + failed++ + } + + // Adding extra new line here to break up the + // results, stops this from being a big wall of + // text and makes it easier to follow. + fmt.Fprint(&message, "\n") } fmt.Fprint(out, message.String()) + summary := fmt.Sprintf("%d chart(s) linted, %d chart(s) failed", len(paths), failed) if failed > 0 { return errors.New(summary) } - fmt.Fprintln(out, summary) + if !client.Quiet || errorsOrWarnings > 0 { + fmt.Fprintln(out, summary) + } return nil }, } @@ -123,6 +161,7 @@ func newLintCmd(out io.Writer) *cobra.Command { f.BoolVar(&client.Quiet, "quiet", false, "print only warnings and errors") f.StringVar(&kubeVersion, "kube-version", "", "Kubernetes version used for capabilities and deprecation checks") f.StringVar(&lintIgnoreFile, "lint-ignore-file", "", "path to .helmlintignore file to specify ignore patterns") + addValueOptionsFlags(f, valueOpts) return cmd -} \ No newline at end of file +}