fix(lint): Return non-zero exit status when lint errors present

pull/907/head
Adnan Abdulhussein 9 years ago
parent da2f7e96e3
commit 77820c7482

@ -28,6 +28,7 @@ import (
"k8s.io/helm/pkg/chartutil" "k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/lint" "k8s.io/helm/pkg/lint"
"k8s.io/helm/pkg/lint/support"
) )
var longLintHelp = ` var longLintHelp = `
@ -51,6 +52,7 @@ func init() {
} }
var errLintNoChart = errors.New("no chart found for linting (missing Chart.yaml)") var errLintNoChart = errors.New("no chart found for linting (missing Chart.yaml)")
var errLintFailed = errors.New("lint failed")
func lintCmd(cmd *cobra.Command, args []string) error { func lintCmd(cmd *cobra.Command, args []string) error {
path := "." path := "."
@ -92,15 +94,20 @@ func lintChart(path string) error {
return errLintNoChart return errLintNoChart
} }
issues := lint.All(path) linter := lint.All(path)
if len(issues) == 0 { if len(linter.Messages) == 0 {
fmt.Println("Lint OK") fmt.Println("Lint OK")
return nil
} }
for _, i := range issues { for _, i := range linter.Messages {
fmt.Printf("%s\n", i) fmt.Printf("%s\n", i)
} }
if linter.HighestSeverity == support.ErrorSev {
return errLintFailed
}
return nil return nil
} }

@ -24,8 +24,7 @@ import (
) )
// All runs all of the available linters on the given base directory. // All runs all of the available linters on the given base directory.
func All(basedir string) []support.Message { func All(basedir string) support.Linter {
// Using abs path to get directory context // Using abs path to get directory context
chartDir, _ := filepath.Abs(basedir) chartDir, _ := filepath.Abs(basedir)
@ -33,5 +32,5 @@ func All(basedir string) []support.Message {
rules.Chartfile(&linter) rules.Chartfile(&linter)
rules.Values(&linter) rules.Values(&linter)
rules.Templates(&linter) rules.Templates(&linter)
return linter.Messages return linter
} }

@ -17,9 +17,10 @@ limitations under the License.
package lint package lint
import ( import (
"k8s.io/helm/pkg/lint/support"
"strings" "strings"
"k8s.io/helm/pkg/lint/support"
"testing" "testing"
) )
@ -29,7 +30,7 @@ const badYamlFileDir = "rules/testdata/albatross"
const goodChartDir = "rules/testdata/goodone" const goodChartDir = "rules/testdata/goodone"
func TestBadChart(t *testing.T) { func TestBadChart(t *testing.T) {
m := All(badChartDir) m := All(badChartDir).Messages
if len(m) != 4 { if len(m) != 4 {
t.Errorf("Number of errors %v", len(m)) t.Errorf("Number of errors %v", len(m))
t.Errorf("All didn't fail with expected errors, got %#v", m) t.Errorf("All didn't fail with expected errors, got %#v", m)
@ -60,7 +61,7 @@ func TestBadChart(t *testing.T) {
} }
func TestInvalidYaml(t *testing.T) { func TestInvalidYaml(t *testing.T) {
m := All(badYamlFileDir) m := All(badYamlFileDir).Messages
if len(m) != 1 { if len(m) != 1 {
t.Errorf("All didn't fail with expected errors, got %#v", m) t.Errorf("All didn't fail with expected errors, got %#v", m)
} }
@ -70,7 +71,7 @@ func TestInvalidYaml(t *testing.T) {
} }
func TestBadValues(t *testing.T) { func TestBadValues(t *testing.T) {
m := All(badValuesFileDir) m := All(badValuesFileDir).Messages
if len(m) != 1 { if len(m) != 1 {
t.Errorf("All didn't fail with expected errors, got %#v", m) t.Errorf("All didn't fail with expected errors, got %#v", m)
} }
@ -80,7 +81,7 @@ func TestBadValues(t *testing.T) {
} }
func TestGoodChart(t *testing.T) { func TestGoodChart(t *testing.T) {
m := All(goodChartDir) m := All(goodChartDir).Messages
if len(m) != 0 { if len(m) != 0 {
t.Errorf("All failed but shouldn't have: %#v", m) t.Errorf("All failed but shouldn't have: %#v", m)
} }

@ -44,7 +44,9 @@ type Message struct {
// Linter encapsulates a linting run of a particular chart. // Linter encapsulates a linting run of a particular chart.
type Linter struct { type Linter struct {
Messages []Message Messages []Message
ChartDir string // The highest severity of all the failing lint rules
HighestSeverity int
ChartDir string
} }
// LintError describes an error encountered while linting. // LintError describes an error encountered while linting.
@ -68,6 +70,10 @@ func (l *Linter) RunLinterRule(severity int, lintError LintError) bool {
if lintError != nil { if lintError != nil {
l.Messages = append(l.Messages, Message{Text: lintError.Error(), Severity: severity}) l.Messages = append(l.Messages, Message{Text: lintError.Error(), Severity: severity})
if severity > l.HighestSeverity {
l.HighestSeverity = severity
}
} }
return lintError == nil return lintError == nil
} }

@ -26,26 +26,31 @@ var lintError LintError = fmt.Errorf("Foobar")
func TestRunLinterRule(t *testing.T) { func TestRunLinterRule(t *testing.T) {
var tests = []struct { var tests = []struct {
Severity int Severity int
LintError error LintError error
ExpectedMessages int ExpectedMessages int
ExpectedReturn bool ExpectedReturn bool
ExpectedHighestSeverity int
}{ }{
{ErrorSev, lintError, 1, false}, {InfoSev, lintError, 1, false, InfoSev},
{WarningSev, lintError, 2, false}, {WarningSev, lintError, 2, false, WarningSev},
{InfoSev, lintError, 3, false}, {ErrorSev, lintError, 3, false, ErrorSev},
// No error so it returns true // No error so it returns true
{ErrorSev, nil, 3, true}, {ErrorSev, nil, 3, true, ErrorSev},
// Invalid severity values // Invalid severity values
{4, lintError, 3, false}, {4, lintError, 3, false, ErrorSev},
{22, lintError, 3, false}, {22, lintError, 3, false, ErrorSev},
{-1, lintError, 3, false}, {-1, lintError, 3, false, ErrorSev},
} }
for _, test := range tests { for _, test := range tests {
isValid := linter.RunLinterRule(test.Severity, test.LintError) isValid := linter.RunLinterRule(test.Severity, test.LintError)
if len(linter.Messages) != test.ExpectedMessages { if len(linter.Messages) != test.ExpectedMessages {
t.Errorf("RunLinterRule(%d, %v), linter.Messages should have now %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages)) t.Errorf("RunLinterRule(%d, %v), linter.Messages should now have %d message, we got %d", test.Severity, test.LintError, test.ExpectedMessages, len(linter.Messages))
}
if linter.HighestSeverity != test.ExpectedHighestSeverity {
t.Errorf("RunLinterRule(%d, %v), linter.HighestSeverity should be %d, we got %d", test.Severity, test.LintError, test.ExpectedHighestSeverity, linter.HighestSeverity)
} }
if isValid != test.ExpectedReturn { if isValid != test.ExpectedReturn {

Loading…
Cancel
Save