Skip to content

Commit 2427c3d

Browse files
committed
chore(golang): refactor go version check for per-plugin configuration
Signed-off-by: Eric Stroczynski <[email protected]>
1 parent 7259fba commit 2427c3d

File tree

4 files changed

+71
-46
lines changed

4 files changed

+71
-46
lines changed

pkg/plugins/golang/go_version.go

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,34 @@ const (
2929
)
3030

3131
var (
32-
go113 = goVersion{
33-
major: 1,
34-
minor: 13,
35-
}
36-
goVerMax = goVersion{
37-
major: 1,
38-
minor: 17,
39-
prerelease: "alpha1",
40-
}
41-
4232
goVerRegexp = regexp.MustCompile(goVerPattern)
4333
)
4434

45-
type goVersion struct {
35+
// GoVersion describes a Go version.
36+
type GoVersion struct {
4637
major, minor, patch int
4738
prerelease string
4839
}
4940

50-
func (v *goVersion) parse(verStr string) error {
41+
func (v GoVersion) String() string {
42+
switch {
43+
case v.patch != 0:
44+
return fmt.Sprintf("go%d.%d.%d", v.major, v.minor, v.patch)
45+
case v.prerelease != "":
46+
return fmt.Sprintf("go%d.%d%s", v.major, v.minor, v.prerelease)
47+
}
48+
return fmt.Sprintf("go%d.%d", v.major, v.minor)
49+
}
50+
51+
// MustParse will panic if verStr does not match the expected Go version string spec.
52+
func MustParse(verStr string) (v GoVersion) {
53+
if err := v.parse(verStr); err != nil {
54+
panic(err)
55+
}
56+
return v
57+
}
58+
59+
func (v *GoVersion) parse(verStr string) error {
5160
m := goVerRegexp.FindStringSubmatch(verStr)
5261
if m == nil {
5362
return fmt.Errorf("invalid version string")
@@ -77,7 +86,8 @@ func (v *goVersion) parse(verStr string) error {
7786
return nil
7887
}
7988

80-
func (v goVersion) compare(other goVersion) int {
89+
// Compare returns -1, 0, or 1 if v < other, v == other, or v > other, respectively.
90+
func (v GoVersion) Compare(other GoVersion) int {
8191
if v.major > other.major {
8292
return 1
8393
}
@@ -114,16 +124,16 @@ func (v goVersion) compare(other goVersion) int {
114124
return -1
115125
}
116126

117-
// ValidateGoVersion verifies that Go is installed and the current go version is supported by kubebuilder
118-
func ValidateGoVersion() error {
119-
err := fetchAndCheckGoVersion()
127+
// ValidateGoVersion verifies that Go is installed and the current go version is supported by a plugin.
128+
func ValidateGoVersion(min, max GoVersion) error {
129+
err := fetchAndCheckGoVersion(min, max)
120130
if err != nil {
121131
return fmt.Errorf("%s. You can skip this check using the --skip-go-version-check flag", err)
122132
}
123133
return nil
124134
}
125135

126-
func fetchAndCheckGoVersion() error {
136+
func fetchAndCheckGoVersion(min, max GoVersion) error {
127137
cmd := exec.Command("go", "version")
128138
out, err := cmd.Output()
129139
if err != nil {
@@ -135,22 +145,20 @@ func fetchAndCheckGoVersion() error {
135145
return fmt.Errorf("found invalid Go version: %q", string(out))
136146
}
137147
goVer := split[2]
138-
if err := checkGoVersion(goVer); err != nil {
148+
if err := checkGoVersion(goVer, min, max); err != nil {
139149
return fmt.Errorf("go version '%s' is incompatible because '%s'", goVer, err)
140150
}
141151
return nil
142152
}
143153

144-
// checkGoVersion should only ever check if the Go version >= 1.13, since the kubebuilder binary only cares
145-
// that the go binary supports go modules which were stabilized in that version (i.e. in go 1.13) by default
146-
func checkGoVersion(verStr string) error {
147-
var version goVersion
154+
func checkGoVersion(verStr string, min, max GoVersion) error {
155+
var version GoVersion
148156
if err := version.parse(verStr); err != nil {
149157
return err
150158
}
151159

152-
if version.compare(go113) < 0 || version.compare(goVerMax) >= 0 {
153-
return fmt.Errorf("requires 1.13 <= version < 1.17")
160+
if version.Compare(min) < 0 || version.Compare(max) >= 0 {
161+
return fmt.Errorf("plugin requires %s <= version < %s", min, max)
154162
}
155163

156164
return nil

pkg/plugins/golang/go_version_test.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,42 +24,42 @@ import (
2424
. "github.com/onsi/gomega"
2525
)
2626

27-
var _ = Describe("goVersion", func() {
27+
var _ = Describe("GoVersion", func() {
2828
Context("parse", func() {
29-
var v goVersion
29+
var v GoVersion
3030

3131
BeforeEach(func() {
32-
v = goVersion{}
32+
v = GoVersion{}
3333
})
3434

3535
DescribeTable("should succeed for valid versions",
36-
func(version string, expected goVersion) {
36+
func(version string, expected GoVersion) {
3737
Expect(v.parse(version)).NotTo(HaveOccurred())
3838
Expect(v.major).To(Equal(expected.major))
3939
Expect(v.minor).To(Equal(expected.minor))
4040
Expect(v.patch).To(Equal(expected.patch))
4141
Expect(v.prerelease).To(Equal(expected.prerelease))
4242
},
43-
Entry("for minor release", "go1.15", goVersion{
43+
Entry("for minor release", "go1.15", GoVersion{
4444
major: 1,
4545
minor: 15,
4646
}),
47-
Entry("for patch release", "go1.15.1", goVersion{
47+
Entry("for patch release", "go1.15.1", GoVersion{
4848
major: 1,
4949
minor: 15,
5050
patch: 1,
5151
}),
52-
Entry("for alpha release", "go1.15alpha1", goVersion{
52+
Entry("for alpha release", "go1.15alpha1", GoVersion{
5353
major: 1,
5454
minor: 15,
5555
prerelease: "alpha1",
5656
}),
57-
Entry("for beta release", "go1.15beta1", goVersion{
57+
Entry("for beta release", "go1.15beta1", GoVersion{
5858
major: 1,
5959
minor: 15,
6060
prerelease: "beta1",
6161
}),
62-
Entry("for release candidate", "go1.15rc1", goVersion{
62+
Entry("for release candidate", "go1.15rc1", GoVersion{
6363
major: 1,
6464
minor: 15,
6565
prerelease: "rc1",
@@ -78,10 +78,10 @@ var _ = Describe("goVersion", func() {
7878
)
7979
})
8080

81-
Context("compare", func() {
82-
// Test compare() by sorting a list.
81+
Context("Compare", func() {
82+
// Test Compare() by sorting a list.
8383
var (
84-
versions = []goVersion{
84+
versions = []GoVersion{
8585
{major: 1, minor: 15, prerelease: "rc2"},
8686
{major: 1, minor: 15, patch: 1},
8787
{major: 1, minor: 16},
@@ -98,7 +98,7 @@ var _ = Describe("goVersion", func() {
9898
{major: 0, minor: 123},
9999
}
100100

101-
sortedVersions = []goVersion{
101+
sortedVersions = []GoVersion{
102102
{major: 0, minor: 123},
103103
{major: 1, minor: 13},
104104
{major: 1, minor: 14},
@@ -118,16 +118,19 @@ var _ = Describe("goVersion", func() {
118118

119119
It("sorts a valid list of versions correctly", func() {
120120
sort.Slice(versions, func(i int, j int) bool {
121-
return versions[i].compare(versions[j]) == -1
121+
return versions[i].Compare(versions[j]) == -1
122122
})
123123
Expect(versions).To(Equal(sortedVersions))
124124
})
125125
})
126126
})
127127

128128
var _ = Describe("checkGoVersion", func() {
129-
DescribeTable("should return true for supported go versions",
130-
func(version string) { Expect(checkGoVersion(version)).NotTo(HaveOccurred()) },
129+
goVerMin := MustParse("go1.13")
130+
goVerMax := MustParse("go2.0alpha1")
131+
132+
DescribeTable("should return no error for supported go versions",
133+
func(version string) { Expect(checkGoVersion(version, goVerMin, goVerMax)).To(Succeed()) },
131134
Entry("for go 1.13", "go1.13"),
132135
Entry("for go 1.13.1", "go1.13.1"),
133136
Entry("for go 1.13.2", "go1.13.2"),
@@ -181,11 +184,13 @@ var _ = Describe("checkGoVersion", func() {
181184
Entry("for go 1.16.4", "go1.16.4"),
182185
)
183186

184-
DescribeTable("should return false for non-supported go versions",
185-
func(version string) { Expect(checkGoVersion(version)).To(HaveOccurred()) },
187+
DescribeTable("should return an error for non-supported go versions",
188+
func(version string) { Expect(checkGoVersion(version, goVerMin, goVerMax)).NotTo(Succeed()) },
186189
Entry("for invalid go versions", "go"),
187190
Entry("for go 1.13beta1", "go1.13beta1"),
188191
Entry("for go 1.13rc1", "go1.13rc1"),
189192
Entry("for go 1.13rc2", "go1.13rc2"),
193+
Entry("for go 2.0alpha1", "go2.0alpha1"),
194+
Entry("for go 2.0.0", "go2.0.0"),
190195
)
191196
})

pkg/plugins/golang/v2/init.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ import (
3434
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds"
3535
)
3636

37+
// Variables and function to check Go version requirements.
38+
var (
39+
goVerMin = golang.MustParse("go1.13")
40+
goVerMax = golang.MustParse("go2.0alpha1")
41+
)
42+
3743
var _ plugin.InitSubcommand = &initSubcommand{}
3844

3945
type initSubcommand struct {
@@ -134,9 +140,9 @@ func (p *initSubcommand) InjectConfig(c config.Config) error {
134140
}
135141

136142
func (p *initSubcommand) PreScaffold(machinery.Filesystem) error {
137-
// Validate the supported go versions
143+
// Ensure Go version is in the allowed range if check not turned off.
138144
if !p.skipGoVersionCheck {
139-
if err := golang.ValidateGoVersion(); err != nil {
145+
if err := golang.ValidateGoVersion(goVerMin, goVerMax); err != nil {
140146
return err
141147
}
142148
}

pkg/plugins/golang/v3/init.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ import (
3333
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v3/scaffolds"
3434
)
3535

36+
// Variables and function to check Go version requirements.
37+
var (
38+
goVerMin = golang.MustParse("go1.16")
39+
goVerMax = golang.MustParse("go2.0alpha1")
40+
)
41+
3642
var _ plugin.InitSubcommand = &initSubcommand{}
3743

3844
type initSubcommand struct {
@@ -106,9 +112,9 @@ func (p *initSubcommand) InjectConfig(c config.Config) error {
106112
}
107113

108114
func (p *initSubcommand) PreScaffold(machinery.Filesystem) error {
109-
// Requires go1.11+
115+
// Ensure Go version is in the allowed range if check not turned off.
110116
if !p.skipGoVersionCheck {
111-
if err := golang.ValidateGoVersion(); err != nil {
117+
if err := golang.ValidateGoVersion(goVerMin, goVerMax); err != nil {
112118
return err
113119
}
114120
}

0 commit comments

Comments
 (0)