Skip to content

Commit 464b509

Browse files
authored
Merge pull request #23 from inteon/improve_linter_diff
Rewrite and fix linter diffing logic
2 parents 32122e4 + dc334d0 commit 464b509

File tree

10 files changed

+336
-247
lines changed

10 files changed

+336
-247
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/go-openapi/swag v0.22.3 // indirect
2020
github.com/golang/protobuf v1.5.2 // indirect
2121
github.com/google/gnostic-models v0.6.8 // indirect
22+
github.com/google/go-cmp v0.5.8 // indirect
2223
github.com/google/uuid v1.5.0 // indirect
2324
github.com/huandu/xstrings v1.4.0 // indirect
2425
github.com/imdario/mergo v0.3.16 // indirect

go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw
2020
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
2121
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
2222
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
23-
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
2423
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
24+
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
25+
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
2526
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
2627
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
2728
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -103,8 +104,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
103104
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
104105
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
105106
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
106-
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
107-
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
108107
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
109108
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
110109
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=

linter/diff.go

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -17,72 +17,25 @@ limitations under the License.
1717
package linter
1818

1919
import (
20-
"sort"
21-
"strings"
20+
"github.com/cert-manager/helm-tool/linter/sets"
2221
)
2322

24-
func DiffPaths(pathsA []string, pathsB []string) ([]string, []string) {
25-
sort.Strings(pathsA)
26-
sort.Strings(pathsB)
27-
28-
missingA := []string{}
29-
missingB := []string{}
30-
31-
prefix := "<NOT A PREFIX>"
32-
var i, j int
33-
for i < len(pathsA) && j < len(pathsB) {
34-
pathA := pathsA[i]
35-
pathB := pathsB[j]
36-
37-
pathAHasPrefix := strings.HasPrefix(pathA, prefix)
38-
pathBHasPrefix := strings.HasPrefix(pathB, prefix)
39-
40-
if pathA == pathB {
41-
prefix = pathA
42-
i++
43-
j++
44-
continue
45-
}
46-
47-
if pathBHasPrefix && pathAHasPrefix {
48-
prefix = "<NOT A PREFIX>"
49-
continue
50-
}
51-
52-
if pathA < pathB {
53-
if !pathAHasPrefix {
54-
missingB = append(missingB, pathA)
55-
}
56-
i++
57-
} else {
58-
if !pathBHasPrefix {
59-
missingA = append(missingA, pathB)
60-
}
61-
j++
62-
}
63-
}
64-
65-
for i < len(pathsA) {
66-
pathA := pathsA[i]
67-
68-
pathAHasPrefix := strings.HasPrefix(pathA, prefix)
69-
if !pathAHasPrefix {
70-
missingB = append(missingB, pathA)
71-
}
72-
73-
i++
74-
}
75-
76-
for j < len(pathsB) {
77-
pathB := pathsB[j]
78-
79-
pathBHasPrefix := strings.HasPrefix(pathB, prefix)
80-
if !pathBHasPrefix {
81-
missingA = append(missingA, pathB)
82-
}
83-
84-
j++
85-
}
23+
// DiffPaths returns the paths that are missing from each set.
24+
// We consider a path to be missing if it is not present in the
25+
// other set, and if it is not a prefix or an extension of another
26+
// path in the other set. We consider a string a prefix of another
27+
// string if the other string starts with the first string followed
28+
// by a period or an opening square bracket.
29+
func DiffPaths(pathsA sets.Set[string], pathsB sets.Set[string]) (sets.Set[string], sets.Set[string]) {
30+
pathsA, pathsB = sets.RemovePrefixes(pathsA), sets.RemovePrefixes(pathsB)
31+
32+
missingA := sets.Remove(pathsB, pathsA)
33+
missingA = sets.RemovePrefixes(missingA, pathsA)
34+
missingA = sets.RemoveExtensions(missingA, pathsA)
35+
36+
missingB := sets.Remove(pathsA, pathsB)
37+
missingB = sets.RemovePrefixes(missingB, pathsB)
38+
missingB = sets.RemoveExtensions(missingB, pathsB)
8639

8740
return missingA, missingB
8841
}

linter/diff_test.go

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,78 +19,85 @@ package linter
1919
import (
2020
"testing"
2121

22+
"github.com/cert-manager/helm-tool/linter/sets"
2223
"github.com/stretchr/testify/require"
2324
)
2425

2526
func TestDiffPaths(t *testing.T) {
2627
type testcase struct {
27-
a []string
28-
b []string
29-
wantMissingA []string
30-
wantMissingB []string
28+
a sets.Set[string]
29+
b sets.Set[string]
30+
wantMissingA sets.Set[string]
31+
wantMissingB sets.Set[string]
3132
}
3233

3334
testcases := []testcase{
3435
{
35-
a: []string{".$", ".$.a", ".$.b", ".$.c"},
36-
b: []string{".$", ".$.a", ".$.b", ".$.c"},
37-
wantMissingA: []string{},
38-
wantMissingB: []string{},
36+
a: sets.New("a", "b", "c"),
37+
b: sets.New("a", "b", "c"),
38+
wantMissingA: sets.New[string](),
39+
wantMissingB: sets.New[string](),
3940
},
4041
{
41-
a: []string{".$", ".$.a", ".$.b", ".$.c"},
42-
b: []string{".$", ".$.a", ".$.b"},
43-
wantMissingA: []string{},
44-
wantMissingB: []string{".$.c"},
42+
a: sets.New("a", "b", "c"),
43+
b: sets.New("a", "b"),
44+
wantMissingA: sets.New[string](),
45+
wantMissingB: sets.New("c"),
4546
},
4647
{
47-
a: []string{".$", ".$.a", ".$.b"},
48-
b: []string{".$", ".$.a", ".$.b", ".$.c"},
49-
wantMissingA: []string{".$.c"},
50-
wantMissingB: []string{},
48+
a: sets.New("a", "b"),
49+
b: sets.New("a", "b", "c"),
50+
wantMissingA: sets.New("c"),
51+
wantMissingB: sets.New[string](),
5152
},
5253
{
53-
a: []string{".$", ".$.a", ".$.a.b"},
54-
b: []string{".$", ".$.a"},
55-
wantMissingA: []string{},
56-
wantMissingB: []string{},
54+
a: sets.New("a.b"),
55+
b: sets.New("a"),
56+
wantMissingA: sets.New[string](),
57+
wantMissingB: sets.New[string](),
5758
},
5859
{
59-
a: []string{".$", ".$.a", ".$.a.b"},
60-
b: []string{".$", ".$.a", ".$.a.c"},
61-
wantMissingA: []string{".$.a.c"},
62-
wantMissingB: []string{".$.a.b"},
60+
a: sets.New("a.b"),
61+
b: sets.New("a.c"),
62+
wantMissingA: sets.New("a.c"),
63+
wantMissingB: sets.New("a.b"),
6364
},
6465
{
65-
a: []string{".$", ".$.a", ".$.a.b.d"},
66-
b: []string{".$", ".$.a", ".$.a.c"},
67-
wantMissingA: []string{".$.a.c"},
68-
wantMissingB: []string{".$.a.b.d"},
66+
a: sets.New("a.b.d"),
67+
b: sets.New("a.c"),
68+
wantMissingA: sets.New("a.c"),
69+
wantMissingB: sets.New("a.b.d"),
6970
},
7071
{
71-
a: []string{".$", ".$.a", ".$.a.b.d"},
72-
b: []string{".$", ".$.b", ".$.c"},
73-
wantMissingA: []string{".$.b", ".$.c"},
74-
wantMissingB: []string{".$.a", ".$.a.b.d"},
72+
a: sets.New("a.b.d"),
73+
b: sets.New("b", "c"),
74+
wantMissingA: sets.New("b", "c"),
75+
wantMissingB: sets.New("a.b.d"),
7576
},
7677
{
77-
a: []string{".$", ".$.b", ".$.d.e.f"},
78-
b: []string{".$", ".$.a", ".$.b", ".$.b.c", ".$.d.g"},
79-
wantMissingA: []string{".$.a", ".$.d.g"},
80-
wantMissingB: []string{".$.d.e.f"},
78+
a: sets.New("b", "d.e.f"),
79+
b: sets.New("a", "b.c", "d.g"),
80+
wantMissingA: sets.New("a", "d.g"),
81+
wantMissingB: sets.New("d.e.f"),
8182
},
8283
{
83-
a: []string{".$", ".$.a", ".$.a.b", ".$.a.b.c3"},
84-
b: []string{".$", ".$.a", ".$.a.b", ".$.a.b.c1", ".$.a.b.c2", ".$.a.b.c3", ".$.a.b.c4"},
85-
wantMissingA: []string{".$.a.b.c1", ".$.a.b.c2", ".$.a.b.c4"},
86-
wantMissingB: []string{},
84+
a: sets.New("a.b.c3"),
85+
b: sets.New("a.b.c1", "a.b.c2", "a.b.c3", "a.b.c4"),
86+
wantMissingA: sets.New("a.b.c1", "a.b.c2", "a.b.c4"),
87+
wantMissingB: sets.New[string](),
88+
},
89+
{
90+
a: sets.New("app.logLevel", "app.test", "app"),
91+
b: sets.New("app.logLevel", "app.logLevela", "app.name"),
92+
wantMissingA: sets.New("app.logLevela", "app.name"),
93+
wantMissingB: sets.New("app.test"),
8794
},
8895
}
8996

9097
for _, tc := range testcases {
9198
diffA, diffB := DiffPaths(tc.a, tc.b)
9299

93-
require.EqualValues(t, tc.wantMissingA, diffA)
94-
require.EqualValues(t, tc.wantMissingB, diffB)
100+
require.ElementsMatch(t, tc.wantMissingA.UnsortedList(), diffA.UnsortedList())
101+
require.ElementsMatch(t, tc.wantMissingB.UnsortedList(), diffB.UnsortedList())
95102
}
96103
}

linter/linter.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"strings"
2424

2525
"github.com/cert-manager/helm-tool/linter/parsetemplates"
26+
"github.com/cert-manager/helm-tool/linter/sets"
2627
"github.com/cert-manager/helm-tool/parser"
2728
)
2829

@@ -36,17 +37,13 @@ func Lint(
3637
return err
3738
}
3839

39-
valuePathsDict := map[string]struct{}{}
40+
valuePaths := sets.Set[string]{}
4041
for _, section := range document.Sections {
4142
for _, property := range section.Properties {
42-
valuePathsDict[property.Path.PatternString()] = struct{}{}
43+
valuePaths.Insert(property.Path.PatternString())
4344
}
4445
}
45-
valuePathsDict = parsetemplates.MakeUniform(valuePathsDict)
46-
valuePaths := []string{}
47-
for path := range valuePathsDict {
48-
valuePaths = append(valuePaths, path)
49-
}
46+
valuePaths = sets.RemovePrefixes(valuePaths)
5047

5148
exceptionStrings := []string{}
5249
if exceptionsPath != "" {
@@ -61,7 +58,7 @@ func Lint(
6158
missingValues, missingTemplates := DiffPaths(valuePaths, templatePaths)
6259

6360
succeeded := true
64-
for _, missingValue := range missingValues {
61+
for missingValue := range missingValues {
6562
exceptionString := fmt.Sprintf("value missing from values.yaml: %s", missingValue)
6663

6764
if !slices.Contains(exceptionStrings, exceptionString) {
@@ -70,7 +67,7 @@ func Lint(
7067
}
7168
}
7269

73-
for _, missingTemplate := range missingTemplates {
70+
for missingTemplate := range missingTemplates {
7471
exceptionString := fmt.Sprintf("value missing from templates: %s", missingTemplate)
7572

7673
if !slices.Contains(exceptionStrings, exceptionString) {

0 commit comments

Comments
 (0)