Skip to content

Commit 6eac15a

Browse files
committed
improve output, enable structured output formats
Signed-off-by: everettraven <[email protected]>
1 parent bd17ed2 commit 6eac15a

19 files changed

+341
-268
lines changed

Diff for: cli/root.go

+34-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package cli
22

33
import (
4-
"errors"
4+
"fmt"
55
"io"
66
"log"
77
"net/url"
88
"os"
9+
"strings"
910

1011
"github.com/everettraven/crd-diff/pkg/config"
1112
"github.com/everettraven/crd-diff/pkg/loaders/composite"
@@ -28,6 +29,11 @@ func NewRootCommand() *cobra.Command {
2829
)
2930

3031
var configFile string
32+
var outputFormat string
33+
34+
const outputFormatJSON = "json"
35+
const outputFormatYAML = "yaml"
36+
const outputFormatPlainText = "plaintext"
3137

3238
rootCmd := &cobra.Command{
3339
Use: "crd-diff <old> <new>",
@@ -89,16 +95,40 @@ Example use cases:
8995

9096
validator := config.ValidatorForConfig(*cfg)
9197

92-
err = validator.Validate(oldCrd, newCrd)
98+
result := validator.Validate(oldCrd, newCrd)
99+
err = result.Error(0)
93100
if err != nil {
94-
baseErr := errors.New("comparing old and new CustomResourceDefinitions")
95-
log.Fatal(errors.Join(baseErr, err))
101+
switch outputFormat {
102+
case outputFormatPlainText:
103+
var out strings.Builder
104+
out.WriteString("comparing the CRDs identified incompatible changes\n\n")
105+
out.WriteString("Incompatible Changes\n")
106+
out.WriteString(strings.Repeat("-", 10) + "\n")
107+
out.WriteString(err.Error())
108+
out.WriteString(strings.Repeat("-", 10) + "\n")
109+
log.Fatal(out.String())
110+
case outputFormatJSON:
111+
jsonOut, marshalError := result.JSON()
112+
if marshalError != nil {
113+
log.Fatalf("marshalling results to JSON: %w", marshalError)
114+
}
115+
fmt.Print(string(jsonOut))
116+
os.Exit(1)
117+
case outputFormatYAML:
118+
yamlOut, marshalError := result.YAML()
119+
if marshalError != nil {
120+
log.Fatalf("marshalling results to YAML: %w", marshalError)
121+
}
122+
fmt.Print(string(yamlOut))
123+
os.Exit(1)
124+
}
96125
}
97126
},
98127
}
99128

100129
rootCmd.AddCommand(NewVersionCommand())
101130
rootCmd.PersistentFlags().StringVar(&configFile, "config", "", "the filepath to load the check configurations from")
131+
rootCmd.PersistentFlags().StringVar(&outputFormat, "output", "plaintext", "the format the output should take when incompatibilities are identified. May be one of plaintext, json, yaml")
102132

103133
return rootCmd
104134
}

Diff for: pkg/validations/property/default.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,15 @@ package property
33
import (
44
"bytes"
55
"fmt"
6-
7-
"github.com/everettraven/crd-diff/pkg/validations/results"
86
)
97

108
type Default struct{}
119

1210
func (d *Default) Name() string {
13-
return "Default"
11+
return "default"
1412
}
1513

16-
func (d *Default) Validate(diff Diff) (bool, *results.Result) {
14+
func (d *Default) Validate(diff Diff) (bool, error) {
1715
reset := func(diff Diff) Diff {
1816
oldProperty := diff.Old()
1917
newProperty := diff.New()
@@ -33,8 +31,5 @@ func (d *Default) Validate(diff Diff) (bool, *results.Result) {
3331
err = fmt.Errorf("default value changed from %q to %q", string(diff.Old().Default.Raw), string(diff.New().Default.Raw))
3432
}
3533

36-
return IsHandled(diff, reset), &results.Result{
37-
Error: err,
38-
Subresults: []*results.Result{},
39-
}
34+
return IsHandled(diff, reset), err
4035
}

Diff for: pkg/validations/property/enum.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@ package property
33
import (
44
"fmt"
55

6-
"github.com/everettraven/crd-diff/pkg/validations/results"
76
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
87
"k8s.io/apimachinery/pkg/util/sets"
98
)
109

1110
type Enum struct{}
1211

1312
func (e *Enum) Name() string {
14-
return "Enum"
13+
return "enum"
1514
}
1615

17-
func (e *Enum) Validate(diff Diff) (bool, *results.Result) {
16+
func (e *Enum) Validate(diff Diff) (bool, error) {
1817
reset := func(diff Diff) Diff {
1918
oldProperty := diff.Old()
2019
newProperty := diff.New()
@@ -42,8 +41,5 @@ func (e *Enum) Validate(diff Diff) (bool, *results.Result) {
4241
err = fmt.Errorf("enums %v removed from the set of previously allowed values", diffEnums.UnsortedList())
4342
}
4443

45-
return IsHandled(diff, reset), &results.Result{
46-
Error: err,
47-
Subresults: []*results.Result{},
48-
}
44+
return IsHandled(diff, reset), err
4945
}

Diff for: pkg/validations/property/max.go

+12-26
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package property
33
import (
44
"cmp"
55
"fmt"
6-
7-
"github.com/everettraven/crd-diff/pkg/validations/results"
86
)
97

108
func maxVerification[T cmp.Ordered](older *T, newer *T) error {
@@ -21,10 +19,10 @@ func maxVerification[T cmp.Ordered](older *T, newer *T) error {
2119
type Maximum struct{}
2220

2321
func (m *Maximum) Name() string {
24-
return "Maximum"
22+
return "maximum"
2523
}
2624

27-
func (m *Maximum) Validate(diff Diff) (bool, *results.Result) {
25+
func (m *Maximum) Validate(diff Diff) (bool, error) {
2826
reset := func(diff Diff) Diff {
2927
oldProperty := diff.Old()
3028
newProperty := diff.New()
@@ -38,19 +36,16 @@ func (m *Maximum) Validate(diff Diff) (bool, *results.Result) {
3836
err = fmt.Errorf("maximum: %s", err.Error())
3937
}
4038

41-
return IsHandled(diff, reset), &results.Result{
42-
Error: err,
43-
Subresults: []*results.Result{},
44-
}
39+
return IsHandled(diff, reset), err
4540
}
4641

4742
type MaxItems struct{}
4843

4944
func (m *MaxItems) Name() string {
50-
return "MaxItems"
45+
return "maxItems"
5146
}
5247

53-
func (m *MaxItems) Validate(diff Diff) (bool, *results.Result) {
48+
func (m *MaxItems) Validate(diff Diff) (bool, error) {
5449
reset := func(diff Diff) Diff {
5550
oldProperty := diff.Old()
5651
newProperty := diff.New()
@@ -64,19 +59,16 @@ func (m *MaxItems) Validate(diff Diff) (bool, *results.Result) {
6459
err = fmt.Errorf("maxItems: %s", err.Error())
6560
}
6661

67-
return IsHandled(diff, reset), &results.Result{
68-
Error: err,
69-
Subresults: []*results.Result{},
70-
}
62+
return IsHandled(diff, reset), err
7163
}
7264

7365
type MaxLength struct{}
7466

7567
func (m *MaxLength) Name() string {
76-
return "MaxLength"
68+
return "maxLength"
7769
}
7870

79-
func (m *MaxLength) Validate(diff Diff) (bool, *results.Result) {
71+
func (m *MaxLength) Validate(diff Diff) (bool, error) {
8072
reset := func(diff Diff) Diff {
8173
oldProperty := diff.Old()
8274
newProperty := diff.New()
@@ -90,19 +82,16 @@ func (m *MaxLength) Validate(diff Diff) (bool, *results.Result) {
9082
err = fmt.Errorf("maxLength: %s", err.Error())
9183
}
9284

93-
return IsHandled(diff, reset), &results.Result{
94-
Error: err,
95-
Subresults: []*results.Result{},
96-
}
85+
return IsHandled(diff, reset), err
9786
}
9887

9988
type MaxProperties struct{}
10089

10190
func (m *MaxProperties) Name() string {
102-
return "MaxProperties"
91+
return "maxProperties"
10392
}
10493

105-
func (m *MaxProperties) Validate(diff Diff) (bool, *results.Result) {
94+
func (m *MaxProperties) Validate(diff Diff) (bool, error) {
10695
reset := func(diff Diff) Diff {
10796
oldProperty := diff.Old()
10897
newProperty := diff.New()
@@ -116,8 +105,5 @@ func (m *MaxProperties) Validate(diff Diff) (bool, *results.Result) {
116105
err = fmt.Errorf("maxProperties: %s", err.Error())
117106
}
118107

119-
return IsHandled(diff, reset), &results.Result{
120-
Error: err,
121-
Subresults: []*results.Result{},
122-
}
108+
return IsHandled(diff, reset), err
123109
}

Diff for: pkg/validations/property/min.go

+12-26
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package property
33
import (
44
"cmp"
55
"fmt"
6-
7-
"github.com/everettraven/crd-diff/pkg/validations/results"
86
)
97

108
func minVerification[T cmp.Ordered](older *T, newer *T) error {
@@ -21,10 +19,10 @@ func minVerification[T cmp.Ordered](older *T, newer *T) error {
2119
type Minimum struct{}
2220

2321
func (m *Minimum) Name() string {
24-
return "Minimum"
22+
return "minimum"
2523
}
2624

27-
func (m *Minimum) Validate(diff Diff) (bool, *results.Result) {
25+
func (m *Minimum) Validate(diff Diff) (bool, error) {
2826
reset := func(diff Diff) Diff {
2927
oldProperty := diff.Old()
3028
newProperty := diff.New()
@@ -38,19 +36,16 @@ func (m *Minimum) Validate(diff Diff) (bool, *results.Result) {
3836
err = fmt.Errorf("minimum: %s", err.Error())
3937
}
4038

41-
return IsHandled(diff, reset), &results.Result{
42-
Error: err,
43-
Subresults: []*results.Result{},
44-
}
39+
return IsHandled(diff, reset), err
4540
}
4641

4742
type MinItems struct{}
4843

4944
func (m *MinItems) Name() string {
50-
return "MinItems"
45+
return "minItems"
5146
}
5247

53-
func (m *MinItems) Validate(diff Diff) (bool, *results.Result) {
48+
func (m *MinItems) Validate(diff Diff) (bool, error) {
5449
reset := func(diff Diff) Diff {
5550
oldProperty := diff.Old()
5651
newProperty := diff.New()
@@ -64,19 +59,16 @@ func (m *MinItems) Validate(diff Diff) (bool, *results.Result) {
6459
err = fmt.Errorf("minItems: %s", err.Error())
6560
}
6661

67-
return IsHandled(diff, reset), &results.Result{
68-
Error: err,
69-
Subresults: []*results.Result{},
70-
}
62+
return IsHandled(diff, reset), err
7163
}
7264

7365
type MinLength struct{}
7466

7567
func (m *MinLength) Name() string {
76-
return "MinLength"
68+
return "minLength"
7769
}
7870

79-
func (m *MinLength) Validate(diff Diff) (bool, *results.Result) {
71+
func (m *MinLength) Validate(diff Diff) (bool, error) {
8072
reset := func(diff Diff) Diff {
8173
oldProperty := diff.Old()
8274
newProperty := diff.New()
@@ -90,19 +82,16 @@ func (m *MinLength) Validate(diff Diff) (bool, *results.Result) {
9082
err = fmt.Errorf("minLength: %s", err.Error())
9183
}
9284

93-
return IsHandled(diff, reset), &results.Result{
94-
Error: err,
95-
Subresults: []*results.Result{},
96-
}
85+
return IsHandled(diff, reset), err
9786
}
9887

9988
type MinProperties struct{}
10089

10190
func (m *MinProperties) Name() string {
102-
return "MinProperties"
91+
return "minProperties"
10392
}
10493

105-
func (m *MinProperties) Validate(diff Diff) (bool, *results.Result) {
94+
func (m *MinProperties) Validate(diff Diff) (bool, error) {
10695
reset := func(diff Diff) Diff {
10796
oldProperty := diff.Old()
10897
newProperty := diff.New()
@@ -116,8 +105,5 @@ func (m *MinProperties) Validate(diff Diff) (bool, *results.Result) {
116105
err = fmt.Errorf("minProperties: %s", err.Error())
117106
}
118107

119-
return IsHandled(diff, reset), &results.Result{
120-
Error: err,
121-
Subresults: []*results.Result{},
122-
}
108+
return IsHandled(diff, reset), err
123109
}

Diff for: pkg/validations/property/property.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package property
22

33
import (
4-
"github.com/everettraven/crd-diff/pkg/validations/results"
54
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
65
)
76

@@ -31,6 +30,6 @@ func (pd *diff) New() *apiextensionsv1.JSONSchemaProps {
3130
}
3231

3332
type Validation interface {
34-
Validate(Diff) (bool, *results.Result)
33+
Validate(Diff) (bool, error)
3534
Name() string
3635
}

Diff for: pkg/validations/property/required.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@ package property
33
import (
44
"fmt"
55

6-
"github.com/everettraven/crd-diff/pkg/validations/results"
76
"k8s.io/apimachinery/pkg/util/sets"
87
)
98

109
type Required struct{}
1110

1211
func (r *Required) Name() string {
13-
return "Required"
12+
return "required"
1413
}
1514

16-
func (r *Required) Validate(diff Diff) (bool, *results.Result) {
15+
func (r *Required) Validate(diff Diff) (bool, error) {
1716
reset := func(diff Diff) Diff {
1817
oldProperty := diff.Old()
1918
newProperty := diff.New()
@@ -31,8 +30,5 @@ func (r *Required) Validate(diff Diff) (bool, *results.Result) {
3130
err = fmt.Errorf("new required fields %v added", diffRequired.UnsortedList())
3231
}
3332

34-
return IsHandled(diff, reset), &results.Result{
35-
Error: err,
36-
Subresults: []*results.Result{},
37-
}
33+
return IsHandled(diff, reset), err
3834
}

0 commit comments

Comments
 (0)