Skip to content

Commit 8c40ed5

Browse files
committed
Change output to be more line orientated
This brings the output inline with the discussions around Conftest. This makes each line a meaninful error or message, and cuts down on some of the repeated output. Individual lines can now be parsed as errors or warnings or passes without knowing the colour.
1 parent 092e382 commit 8c40ed5

File tree

5 files changed

+56
-52
lines changed

5 files changed

+56
-52
lines changed

acceptance.bats

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,49 @@
33
@test "Pass when parsing a valid Kubernetes config YAML file" {
44
run bin/kubeval fixtures/valid.yaml
55
[ "$status" -eq 0 ]
6-
[ "$output" = "The file fixtures/valid.yaml contains a valid ReplicationController" ]
6+
[ "$output" = "PASS - fixtures/valid.yaml contains a valid ReplicationController" ]
77
}
88

99
@test "Pass when parsing a valid Kubernetes config YAML file on stdin" {
1010
run bash -c "cat fixtures/valid.yaml | bin/kubeval"
1111
[ "$status" -eq 0 ]
12-
[ "$output" = "The file stdin contains a valid ReplicationController" ]
12+
[ "$output" = "PASS - stdin contains a valid ReplicationController" ]
1313
}
1414

1515
@test "Pass when parsing a valid Kubernetes config YAML file explicitly on stdin" {
1616
run bash -c "cat fixtures/valid.yaml | bin/kubeval -"
1717
[ "$status" -eq 0 ]
18-
[ "$output" = "The file stdin contains a valid ReplicationController" ]
18+
[ "$output" = "PASS - stdin contains a valid ReplicationController" ]
1919
}
2020

2121
@test "Pass when parsing a valid Kubernetes config JSON file" {
2222
run bin/kubeval fixtures/valid.json
2323
[ "$status" -eq 0 ]
24-
[ "$output" = "The file fixtures/valid.json contains a valid Deployment" ]
24+
[ "$output" = "PASS - fixtures/valid.json contains a valid Deployment" ]
2525
}
2626

2727
@test "Pass when parsing a Kubernetes file with string and integer quantities" {
2828
run bin/kubeval fixtures/quantity.yaml
2929
[ "$status" -eq 0 ]
30-
[ "$output" = "The file fixtures/quantity.yaml contains a valid LimitRange" ]
30+
[ "$output" = "PASS - fixtures/quantity.yaml contains a valid LimitRange" ]
3131
}
3232

3333
@test "Pass when parsing a valid Kubernetes config file with int_to_string vars" {
3434
run bin/kubeval fixtures/int_or_string.yaml
3535
[ "$status" -eq 0 ]
36-
[ "$output" = "The file fixtures/int_or_string.yaml contains a valid Service" ]
36+
[ "$output" = "PASS - fixtures/int_or_string.yaml contains a valid Service" ]
3737
}
3838

3939
@test "Pass when parsing a valid Kubernetes config file with null arrays" {
4040
run bin/kubeval fixtures/null_array.yaml
4141
[ "$status" -eq 0 ]
42-
[ "$output" = "The file fixtures/null_array.yaml contains a valid Deployment" ]
42+
[ "$output" = "PASS - fixtures/null_array.yaml contains a valid Deployment" ]
4343
}
4444

4545
@test "Pass when parsing a valid Kubernetes config file with null strings" {
4646
run bin/kubeval fixtures/null_string.yaml
4747
[ "$status" -eq 0 ]
48-
[ "$output" = "The file fixtures/null_string.yaml contains a valid Service" ]
48+
[ "$output" = "PASS - fixtures/null_string.yaml contains a valid Service" ]
4949
}
5050

5151
@test "Pass when parsing a multi-document config file" {
@@ -71,19 +71,19 @@
7171
@test "Return relevant error for non-existent file" {
7272
run bin/kubeval fixtures/not-here
7373
[ "$status" -eq 1 ]
74-
[ $(expr "$output" : "^Could not open file") -ne 0 ]
74+
[ $(expr "$output" : "^ERR - Could not open file") -ne 0 ]
7575
}
7676

7777
@test "Pass when parsing a blank config file" {
7878
run bin/kubeval fixtures/blank.yaml
7979
[ "$status" -eq 0 ]
80-
[ "$output" = "The file fixtures/blank.yaml contains an empty YAML document" ]
80+
[ "$output" = "PASS - fixtures/blank.yaml contains an empty YAML document" ]
8181
}
8282

8383
@test "Pass when parsing a blank config file with a comment" {
8484
run bin/kubeval fixtures/comment.yaml
8585
[ "$status" -eq 0 ]
86-
[ "$output" = "The file fixtures/comment.yaml contains an empty YAML document" ]
86+
[ "$output" = "PASS - fixtures/comment.yaml contains an empty YAML document" ]
8787
}
8888

8989
@test "Return relevant error for YAML missing kind key" {
@@ -159,13 +159,13 @@
159159
@test "Only prints a single warning when --ignore-missing-schemas is supplied" {
160160
run bin/kubeval --ignore-missing-schemas fixtures/valid.yaml fixtures/valid.yaml
161161
[ "$status" -eq 0 ]
162-
[[ "${lines[0]}" == *"Warning: Set to ignore missing schemas"* ]]
163-
[[ "${lines[1]}" == *"The file fixtures/valid.yaml contains a valid ReplicationController"* ]]
164-
[[ "${lines[2]}" == *"The file fixtures/valid.yaml contains a valid ReplicationController"* ]]
162+
[[ "${lines[0]}" == *"WARN - Set to ignore missing schemas"* ]]
163+
[[ "${lines[1]}" == *"PASS - fixtures/valid.yaml contains a valid ReplicationController"* ]]
164+
[[ "${lines[2]}" == *"PASS - fixtures/valid.yaml contains a valid ReplicationController"* ]]
165165
}
166166

167167
@test "Does not print warnings if --quiet is supplied" {
168168
run bin/kubeval --ignore-missing-schemas --quiet fixtures/valid.yaml
169169
[ "$status" -eq 0 ]
170-
[ "$output" = "The file fixtures/valid.yaml contains a valid ReplicationController" ]
170+
[ "$output" = "PASS - fixtures/valid.yaml contains a valid ReplicationController" ]
171171
}

kubeval/kubeval.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ func validateResource(data []byte, schemaCache map[string]*gojsonschema.Schema,
110110

111111
kind, err := getString(body, "kind")
112112
if err != nil {
113-
return result, fmt.Errorf("Error with %s: %s", result.FileName, err.Error())
113+
return result, fmt.Errorf("%s: %s", result.FileName, err.Error())
114114
}
115115
result.Kind = kind
116116

117117
apiVersion, err := getString(body, "apiVersion")
118118
if err != nil {
119-
return result, fmt.Errorf("Error with %s: %s", result.FileName, err.Error())
119+
return result, fmt.Errorf("%s: %s", result.FileName, err.Error())
120120
}
121121
result.APIVersion = apiVersion
122122

@@ -126,7 +126,7 @@ func validateResource(data []byte, schemaCache map[string]*gojsonschema.Schema,
126126

127127
schemaErrors, err := validateAgainstSchema(body, &result, schemaCache, config)
128128
if err != nil {
129-
return result, fmt.Errorf("Error with %s: %s", result.FileName, err.Error())
129+
return result, fmt.Errorf("%s: %s", result.FileName, err.Error())
130130
}
131131
result.Errors = schemaErrors
132132
return result, nil
@@ -192,11 +192,11 @@ func downloadSchema(resource *ValidationResult, schemaCache map[string]*gojsonsc
192192
errors = multierror.Append(errors, wrappedErr)
193193
}
194194

195-
if errors != nil {
196-
errors.ErrorFormat = singleLineErrorFormat
197-
}
195+
if errors != nil {
196+
errors.ErrorFormat = singleLineErrorFormat
197+
}
198198

199-
// TODO: this currently triggers a segfault in offline cases
199+
// TODO: this currently triggers a segfault in offline cases
200200
// We couldn't find a schema for this resource. Cache it's lack of existence, then stop
201201
//schemaCache[resource.VersionKind()] = nil
202202
return nil, errors.ErrorOrNil()
@@ -277,16 +277,16 @@ func ValidateWithCache(input []byte, schemaCache map[string]*gojsonschema.Schema
277277
}
278278
}
279279

280-
if errors != nil {
281-
errors.ErrorFormat = singleLineErrorFormat
282-
}
280+
if errors != nil {
281+
errors.ErrorFormat = singleLineErrorFormat
282+
}
283283
return results, errors.ErrorOrNil()
284284
}
285285

286286
func singleLineErrorFormat(es []error) string {
287-
messages := make([]string, len(es))
288-
for i, e := range es {
289-
messages[i] = e.Error()
290-
}
291-
return strings.Join(messages, "\n")
287+
messages := make([]string, len(es))
288+
for i, e := range es {
289+
messages[i] = e.Error()
290+
}
291+
return strings.Join(messages, "\n")
292292
}

kubeval/output.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,15 @@ func newSTDOutputManager() *STDOutputManager {
6060

6161
func (s *STDOutputManager) Put(result ValidationResult) error {
6262
if len(result.Errors) > 0 {
63-
kLog.Warn("The file", result.FileName, "contains an invalid", result.Kind)
6463
for _, desc := range result.Errors {
65-
kLog.Info("--->", desc)
64+
kLog.Warn(result.FileName, "contains an invalid", result.Kind, "-", desc.String())
6665
}
6766
} else if result.Kind == "" {
68-
kLog.Success("The file", result.FileName, "contains an empty YAML document")
67+
kLog.Success(result.FileName, "contains an empty YAML document")
6968
} else if !result.ValidatedAgainstSchema {
70-
kLog.Warn("The file", result.FileName, "containing a", result.Kind, "was not validated against a schema")
69+
kLog.Warn(result.FileName, "containing a", result.Kind, "was not validated against a schema")
7170
} else {
72-
kLog.Success("The file", result.FileName, "contains a valid", result.Kind)
71+
kLog.Success(result.FileName, "contains a valid", result.Kind)
7372
}
7473

7574
return nil

log/log.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,29 @@ package log
22

33
import (
44
"fmt"
5+
"strings"
56

67
"github.com/fatih/color"
8+
multierror "github.com/hashicorp/go-multierror"
79
)
810

9-
func Info(message ...interface{}) {
10-
fmt.Println(message...)
11+
func Success(message ...string) {
12+
green := color.New(color.FgGreen).SprintFunc()
13+
fmt.Printf("%s - %v\n", green("PASS"), strings.Join(message, " "))
1114
}
1215

13-
func Success(message ...interface{}) {
14-
green := color.New(color.FgGreen)
15-
green.Println(message...)
16+
func Warn(message ...string) {
17+
yellow := color.New(color.FgYellow).SprintFunc()
18+
fmt.Printf("%s - %v\n", yellow("WARN"), strings.Join(message, " "))
1619
}
1720

18-
func Warn(message ...interface{}) {
19-
yellow := color.New(color.FgYellow)
20-
yellow.Println(message...)
21-
}
22-
23-
func Error(message ...interface{}) {
24-
red := color.New(color.FgRed)
25-
red.Println(message...)
21+
func Error(message error) {
22+
if merr, ok := message.(*multierror.Error); ok {
23+
for _, serr := range merr.Errors {
24+
Error(serr)
25+
}
26+
} else {
27+
red := color.New(color.FgRed).SprintFunc()
28+
fmt.Printf("%s - %v\n", red("ERR "), message)
29+
}
2630
}

main.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"bufio"
55
"bytes"
6+
"errors"
67
"fmt"
78
"io/ioutil"
89
"os"
@@ -40,7 +41,7 @@ var RootCmd = &cobra.Command{
4041
Version: fmt.Sprintf("Version: %s\nCommit: %s\nDate: %s\n", version, commit, date),
4142
Run: func(cmd *cobra.Command, args []string) {
4243
if config.IgnoreMissingSchemas && !config.Quiet {
43-
log.Warn("Warning: Set to ignore missing schemas")
44+
log.Warn("Set to ignore missing schemas")
4445
}
4546
success := true
4647
windowsStdinIssue := false
@@ -88,13 +89,13 @@ var RootCmd = &cobra.Command{
8889
}
8990
} else {
9091
if len(args) < 1 && len(directories) < 1 {
91-
log.Error("You must pass at least one file as an argument, or at least one directory to the directories flag")
92+
log.Error(errors.New("You must pass at least one file as an argument, or at least one directory to the directories flag"))
9293
os.Exit(1)
9394
}
9495
schemaCache := kubeval.NewSchemaCache()
9596
files, err := aggregateFiles(args)
9697
if err != nil {
97-
log.Error(err.Error())
98+
log.Error(err)
9899
success = false
99100
}
100101

@@ -103,7 +104,7 @@ var RootCmd = &cobra.Command{
103104
filePath, _ := filepath.Abs(fileName)
104105
fileContents, err := ioutil.ReadFile(filePath)
105106
if err != nil {
106-
log.Error("Could not open file", fileName)
107+
log.Error(fmt.Errorf("Could not open file %v", fileName))
107108
earlyExit()
108109
success = false
109110
continue

0 commit comments

Comments
 (0)