Skip to content

Commit 8e0f0ab

Browse files
authored
Merge pull request #2074 from Adirio/export-machinery-utils
🌱 Move the internal machinery utils to appropiate exported packages
2 parents dd3942c + 2687774 commit 8e0f0ab

File tree

10 files changed

+300
-89
lines changed

10 files changed

+300
-89
lines changed
File renamed without changes.
File renamed without changes.

pkg/plugins/internal/util/go_version.go renamed to pkg/plugins/golang/go_version.go

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package util
17+
package golang
1818

1919
import (
2020
"fmt"
@@ -24,6 +24,96 @@ import (
2424
"strings"
2525
)
2626

27+
const (
28+
goVerPattern = `^go(?P<major>[0-9]+)\.(?P<minor>[0-9]+)(?:\.(?P<patch>[0-9]+)|(?P<pre>(?:alpha|beta|rc)[0-9]+))?$`
29+
)
30+
31+
var (
32+
go113 = goVersion{
33+
major: 1,
34+
minor: 13,
35+
}
36+
go116alpha1 = goVersion{
37+
major: 1,
38+
minor: 16,
39+
prerelease: "alpha1",
40+
}
41+
42+
goVerRegexp = regexp.MustCompile(goVerPattern)
43+
)
44+
45+
type goVersion struct {
46+
major, minor, patch int
47+
prerelease string
48+
}
49+
50+
func (v *goVersion) parse(verStr string) error {
51+
m := goVerRegexp.FindStringSubmatch(verStr)
52+
if m == nil {
53+
return fmt.Errorf("invalid version string")
54+
}
55+
56+
var err error
57+
58+
v.major, err = strconv.Atoi(m[1])
59+
if err != nil {
60+
return fmt.Errorf("error parsing major version '%s': %s", m[1], err)
61+
}
62+
63+
v.minor, err = strconv.Atoi(m[2])
64+
if err != nil {
65+
return fmt.Errorf("error parsing minor version '%s': %s", m[2], err)
66+
}
67+
68+
if m[3] != "" {
69+
v.patch, err = strconv.Atoi(m[3])
70+
if err != nil {
71+
return fmt.Errorf("error parsing patch version '%s': %s", m[2], err)
72+
}
73+
}
74+
75+
v.prerelease = m[4]
76+
77+
return nil
78+
}
79+
80+
func (v goVersion) compare(other goVersion) int {
81+
if v.major > other.major {
82+
return 1
83+
}
84+
if v.major < other.major {
85+
return -1
86+
}
87+
88+
if v.minor > other.minor {
89+
return 1
90+
}
91+
if v.minor < other.minor {
92+
return -1
93+
}
94+
95+
if v.patch > other.patch {
96+
return 1
97+
}
98+
if v.patch < other.patch {
99+
return -1
100+
}
101+
102+
if v.prerelease == other.prerelease {
103+
return 0
104+
}
105+
if v.prerelease == "" {
106+
return 1
107+
}
108+
if other.prerelease == "" {
109+
return -1
110+
}
111+
if v.prerelease > other.prerelease {
112+
return 1
113+
}
114+
return -1
115+
}
116+
27117
// ValidateGoVersion verifies that Go is installed and the current go version is supported by kubebuilder
28118
func ValidateGoVersion() error {
29119
err := fetchAndCheckGoVersion()
@@ -54,24 +144,13 @@ func fetchAndCheckGoVersion() error {
54144
// checkGoVersion should only ever check if the Go version >= 1.13, since the kubebuilder binary only cares
55145
// that the go binary supports go modules which were stabilized in that version (i.e. in go 1.13) by default
56146
func checkGoVersion(verStr string) error {
57-
goVerRegex := `^go?([0-9]+)\.([0-9]+)[\.0-9A-Za-z\-]*$`
58-
m := regexp.MustCompile(goVerRegex).FindStringSubmatch(verStr)
59-
if m == nil {
60-
return fmt.Errorf("invalid version string")
61-
}
62-
63-
major, err := strconv.Atoi(m[1])
64-
if err != nil {
65-
return fmt.Errorf("error parsing major version '%s': %s", m[1], err)
66-
}
67-
68-
minor, err := strconv.Atoi(m[2])
69-
if err != nil {
70-
return fmt.Errorf("error parsing minor version '%s': %s", m[2], err)
147+
var version goVersion
148+
if err := version.parse(verStr); err != nil {
149+
return err
71150
}
72151

73-
if major < 1 || minor < 13 {
74-
return fmt.Errorf("requires version >= 1.13")
152+
if version.compare(go113) < 0 || version.compare(go116alpha1) >= 0 {
153+
return fmt.Errorf("requires 1.13 <= version < 1.16")
75154
}
76155

77156
return nil
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package golang
18+
19+
import (
20+
"sort"
21+
22+
. "github.com/onsi/ginkgo"
23+
. "github.com/onsi/ginkgo/extensions/table"
24+
. "github.com/onsi/gomega"
25+
)
26+
27+
var _ = Describe("goVersion", func() {
28+
Context("parse", func() {
29+
var v goVersion
30+
31+
BeforeEach(func() {
32+
v = goVersion{}
33+
})
34+
35+
DescribeTable("should succeed for valid versions",
36+
func(version string, expected goVersion) {
37+
Expect(v.parse(version)).NotTo(HaveOccurred())
38+
Expect(v.major).To(Equal(expected.major))
39+
Expect(v.minor).To(Equal(expected.minor))
40+
Expect(v.patch).To(Equal(expected.patch))
41+
Expect(v.prerelease).To(Equal(expected.prerelease))
42+
},
43+
Entry("for minor release", "go1.15", goVersion{
44+
major: 1,
45+
minor: 15,
46+
}),
47+
Entry("for patch release", "go1.15.1", goVersion{
48+
major: 1,
49+
minor: 15,
50+
patch: 1,
51+
}),
52+
Entry("for alpha release", "go1.15alpha1", goVersion{
53+
major: 1,
54+
minor: 15,
55+
prerelease: "alpha1",
56+
}),
57+
Entry("for beta release", "go1.15beta1", goVersion{
58+
major: 1,
59+
minor: 15,
60+
prerelease: "beta1",
61+
}),
62+
Entry("for release candidate", "go1.15rc1", goVersion{
63+
major: 1,
64+
minor: 15,
65+
prerelease: "rc1",
66+
}),
67+
)
68+
69+
DescribeTable("should fail for invalid versions",
70+
func(version string) { Expect(v.parse(version)).To(HaveOccurred()) },
71+
Entry("for invalid prefix", "g1.15"),
72+
Entry("for missing major version", "go.15"),
73+
Entry("for missing minor version", "go1."),
74+
Entry("for patch and prerelease version", "go1.15.1rc1"),
75+
Entry("for invalid major version", "goa.15"),
76+
Entry("for invalid minor version", "go1.a"),
77+
Entry("for invalid patch version", "go1.15.a"),
78+
)
79+
})
80+
81+
Context("compare", func() {
82+
// Test compare() by sorting a list.
83+
var (
84+
versions = []goVersion{
85+
{major: 1, minor: 15, prerelease: "rc2"},
86+
{major: 1, minor: 15, patch: 1},
87+
{major: 1, minor: 16},
88+
{major: 1, minor: 15, prerelease: "beta1"},
89+
{major: 1, minor: 15, prerelease: "alpha2"},
90+
{major: 2, minor: 0},
91+
{major: 1, minor: 15, prerelease: "alpha1"},
92+
{major: 1, minor: 13},
93+
{major: 1, minor: 15, prerelease: "rc1"},
94+
{major: 1, minor: 15},
95+
{major: 1, minor: 15, patch: 2},
96+
{major: 1, minor: 14},
97+
{major: 1, minor: 15, prerelease: "beta2"},
98+
{major: 0, minor: 123},
99+
}
100+
101+
sortedVersions = []goVersion{
102+
{major: 0, minor: 123},
103+
{major: 1, minor: 13},
104+
{major: 1, minor: 14},
105+
{major: 1, minor: 15, prerelease: "alpha1"},
106+
{major: 1, minor: 15, prerelease: "alpha2"},
107+
{major: 1, minor: 15, prerelease: "beta1"},
108+
{major: 1, minor: 15, prerelease: "beta2"},
109+
{major: 1, minor: 15, prerelease: "rc1"},
110+
{major: 1, minor: 15, prerelease: "rc2"},
111+
{major: 1, minor: 15},
112+
{major: 1, minor: 15, patch: 1},
113+
{major: 1, minor: 15, patch: 2},
114+
{major: 1, minor: 16},
115+
{major: 2, minor: 0},
116+
}
117+
)
118+
119+
It("sorts a valid list of versions correctly", func() {
120+
sort.Slice(versions, func(i int, j int) bool {
121+
return versions[i].compare(versions[j]) == -1
122+
})
123+
Expect(versions).To(Equal(sortedVersions))
124+
})
125+
})
126+
})
127+
128+
var _ = Describe("checkGoVersion", func() {
129+
DescribeTable("should return true for supported go versions",
130+
func(version string) { Expect(checkGoVersion(version)).NotTo(HaveOccurred()) },
131+
Entry("for go 1.13", "go1.13"),
132+
Entry("for go 1.13.1", "go1.13.1"),
133+
Entry("for go 1.13.2", "go1.13.2"),
134+
Entry("for go 1.13.3", "go1.13.3"),
135+
Entry("for go 1.13.4", "go1.13.4"),
136+
Entry("for go 1.13.5", "go1.13.5"),
137+
Entry("for go 1.13.6", "go1.13.6"),
138+
Entry("for go 1.13.7", "go1.13.7"),
139+
Entry("for go 1.13.8", "go1.13.8"),
140+
Entry("for go 1.13.9", "go1.13.9"),
141+
Entry("for go 1.13.10", "go1.13.10"),
142+
Entry("for go 1.13.11", "go1.13.11"),
143+
Entry("for go 1.13.12", "go1.13.12"),
144+
Entry("for go 1.13.13", "go1.13.13"),
145+
Entry("for go 1.13.14", "go1.13.14"),
146+
Entry("for go 1.13.15", "go1.13.15"),
147+
Entry("for go 1.14beta1", "go1.14beta1"),
148+
Entry("for go 1.14rc1", "go1.14rc1"),
149+
Entry("for go 1.14", "go1.14"),
150+
Entry("for go 1.14.1", "go1.14.1"),
151+
Entry("for go 1.14.2", "go1.14.2"),
152+
Entry("for go 1.14.3", "go1.14.3"),
153+
Entry("for go 1.14.4", "go1.14.4"),
154+
Entry("for go 1.14.5", "go1.14.5"),
155+
Entry("for go 1.14.6", "go1.14.6"),
156+
Entry("for go 1.14.7", "go1.14.7"),
157+
Entry("for go 1.14.8", "go1.14.8"),
158+
Entry("for go 1.14.9", "go1.14.9"),
159+
Entry("for go 1.14.10", "go1.14.10"),
160+
Entry("for go 1.14.11", "go1.14.11"),
161+
Entry("for go 1.14.12", "go1.14.12"),
162+
Entry("for go 1.14.13", "go1.14.13"),
163+
Entry("for go 1.14.14", "go1.14.14"),
164+
Entry("for go 1.14.15", "go1.14.15"),
165+
Entry("for go 1.15beta1", "go1.15beta1"),
166+
Entry("for go 1.15rc1", "go1.15rc1"),
167+
Entry("for go 1.15rc2", "go1.15rc2"),
168+
Entry("for go 1.15", "go1.15"),
169+
Entry("for go 1.15.1", "go1.15.1"),
170+
Entry("for go 1.15.2", "go1.15.2"),
171+
Entry("for go 1.15.3", "go1.15.3"),
172+
Entry("for go 1.15.4", "go1.15.4"),
173+
Entry("for go 1.15.5", "go1.15.5"),
174+
Entry("for go 1.15.6", "go1.15.6"),
175+
Entry("for go 1.15.7", "go1.15.7"),
176+
Entry("for go 1.15.8", "go1.15.8"),
177+
)
178+
179+
DescribeTable("should return false for non-supported go versions",
180+
func(version string) { Expect(checkGoVersion(version)).To(HaveOccurred()) },
181+
Entry("for invalid go versions", "go"),
182+
Entry("for go 1.13beta1", "go1.13beta1"),
183+
Entry("for go 1.13rc1", "go1.13rc1"),
184+
Entry("for go 1.13rc2", "go1.13rc2"),
185+
Entry("for go 1.16beta1", "go1.16beta1"),
186+
Entry("for go 1.16rc1", "go1.16rc1"),
187+
Entry("for go 1.16", "go1.16"),
188+
)
189+
})

pkg/plugins/internal/util/repository.go renamed to pkg/plugins/golang/repository.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package util
17+
package golang
1818

1919
import (
2020
"encoding/json"
@@ -34,12 +34,9 @@ type module struct {
3434
}
3535

3636
// findGoModulePath finds the path of the current module, if present.
37-
func findGoModulePath(forceModules bool) (string, error) {
37+
func findGoModulePath() (string, error) {
3838
cmd := exec.Command("go", "mod", "edit", "-json")
3939
cmd.Env = append(cmd.Env, os.Environ()...)
40-
if forceModules {
41-
cmd.Env = append(cmd.Env, "GO111MODULE=on" /* turn on modules just for these commands */)
42-
}
4340
out, err := cmd.Output()
4441
if err != nil {
4542
if exitErr, isExitErr := err.(*exec.ExitError); isExitErr {
@@ -58,7 +55,7 @@ func findGoModulePath(forceModules bool) (string, error) {
5855
// though a combination of go/packages and `go mod` commands/tricks.
5956
func FindCurrentRepo() (string, error) {
6057
// easiest case: existing go module
61-
path, err := findGoModulePath(false)
58+
path, err := findGoModulePath()
6259
if err == nil {
6360
return path, nil
6461
}
@@ -79,7 +76,6 @@ func FindCurrentRepo() (string, error) {
7976
// otherwise, try to get `go mod init` to guess for us -- it's pretty good
8077
cmd := exec.Command("go", "mod", "init")
8178
cmd.Env = append(cmd.Env, os.Environ()...)
82-
cmd.Env = append(cmd.Env, "GO111MODULE=on" /* turn on modules just for these commands */)
8379
if _, err := cmd.Output(); err != nil {
8480
if exitErr, isExitErr := err.(*exec.ExitError); isExitErr {
8581
err = fmt.Errorf("%s", string(exitErr.Stderr))
@@ -90,5 +86,5 @@ func FindCurrentRepo() (string, error) {
9086
}
9187
//nolint:errcheck
9288
defer os.Remove("go.mod") // clean up after ourselves
93-
return findGoModulePath(true)
89+
return findGoModulePath()
9490
}

pkg/plugins/golang/v2/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ import (
3131
"sigs.k8s.io/kubebuilder/v3/pkg/model"
3232
"sigs.k8s.io/kubebuilder/v3/pkg/model/resource"
3333
"sigs.k8s.io/kubebuilder/v3/pkg/plugin"
34+
"sigs.k8s.io/kubebuilder/v3/pkg/plugin/util"
3435
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/golang/v2/scaffolds"
3536
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/cmdutil"
36-
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/internal/util"
3737
"sigs.k8s.io/kubebuilder/v3/plugins/addon"
3838
)
3939

0 commit comments

Comments
 (0)