diff --git a/go.mod b/go.mod index ba3929b79c9e..47399e359c05 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/lasiar/canonicalheader v1.1.2 github.com/ldez/exptostd v0.3.1 github.com/ldez/gomoddirectives v0.6.0 - github.com/ldez/grignotin v0.7.0 + github.com/ldez/grignotin v0.8.0 github.com/ldez/tagliatelle v0.7.1 github.com/ldez/usetesting v0.4.2 github.com/leonklingele/grouper v1.1.2 diff --git a/go.sum b/go.sum index bcf7d18bacb6..486852b11f71 100644 --- a/go.sum +++ b/go.sum @@ -355,8 +355,8 @@ github.com/ldez/exptostd v0.3.1 h1:90yWWoAKMFHeovTK8uzBms9Ppp8Du/xQ20DRO26Ymrw= github.com/ldez/exptostd v0.3.1/go.mod h1:iZBRYaUmcW5jwCR3KROEZ1KivQQp6PHXbDPk9hqJKCQ= github.com/ldez/gomoddirectives v0.6.0 h1:Jyf1ZdTeiIB4dd+2n4qw+g4aI9IJ6JyfOZ8BityWvnA= github.com/ldez/gomoddirectives v0.6.0/go.mod h1:TuwOGYoPAoENDWQpe8DMqEm5nIfjrxZXmxX/CExWyZ4= -github.com/ldez/grignotin v0.7.0 h1:vh0dI32WhHaq6LLPZ38g7WxXuZ1+RzyrJ7iPG9JMa8c= -github.com/ldez/grignotin v0.7.0/go.mod h1:uaVTr0SoZ1KBii33c47O1M8Jp3OP3YDwhZCmzT9GHEk= +github.com/ldez/grignotin v0.8.0 h1:M9QeBN2qyPrqwqx+RhG7W2xKjyV7dRWKjNghbz7fkM0= +github.com/ldez/grignotin v0.8.0/go.mod h1:uaVTr0SoZ1KBii33c47O1M8Jp3OP3YDwhZCmzT9GHEk= github.com/ldez/tagliatelle v0.7.1 h1:bTgKjjc2sQcsgPiT902+aadvMjCeMHrY7ly2XKFORIk= github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I= github.com/ldez/usetesting v0.4.2 h1:J2WwbrFGk3wx4cZwSMiCQQ00kjGR0+tuuyW0Lqm4lwA= diff --git a/pkg/config/config.go b/pkg/config/config.go index 579eddf594a2..c846611838a1 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -9,6 +9,7 @@ import ( "strings" hcversion "github.com/hashicorp/go-version" + "github.com/ldez/grignotin/goenv" "github.com/ldez/grignotin/gomod" "golang.org/x/mod/modfile" ) @@ -80,43 +81,57 @@ func IsGoGreaterThanOrEqual(current, limit string) bool { } func detectGoVersion() string { - goVersion := detectGoVersionFromGoMod() - if goVersion != "" { - return goVersion - } - - return cmp.Or(os.Getenv("GOVERSION"), "1.17") + return cmp.Or(detectGoVersionFromGoMod(), "1.17") } // detectGoVersionFromGoMod tries to get Go version from go.mod. // It returns `toolchain` version if present, // else it returns `go` version if present, +// else it returns `GOVERSION` version if present, // else it returns empty. func detectGoVersionFromGoMod() string { - modPath, err := gomod.GetGoModPath() + values, err := goenv.Get(goenv.GOMOD, goenv.GOVERSION) if err != nil { - modPath = detectGoModFallback() - if modPath == "" { - return "" + values = map[string]string{ + goenv.GOMOD: detectGoModFallback(), } } - file, err := parseGoMod(modPath) + if values[goenv.GOMOD] == "" { + return parseGoVersion(values[goenv.GOVERSION]) + } + + file, err := parseGoMod(values[goenv.GOMOD]) if err != nil { - return "" + return parseGoVersion(values[goenv.GOVERSION]) } // The toolchain exists only if 'toolchain' version > 'go' version. // If 'toolchain' version <= 'go' version, `go mod tidy` will remove 'toolchain' version from go.mod. if file.Toolchain != nil && file.Toolchain.Name != "" { - return strings.TrimPrefix(file.Toolchain.Name, "go") + return parseGoVersion(file.Toolchain.Name) } if file.Go != nil && file.Go.Version != "" { return file.Go.Version } - return "" + return parseGoVersion(values[goenv.GOVERSION]) +} + +func parseGoVersion(v string) string { + raw := strings.TrimPrefix(v, "go") + + // prerelease version (ex: go1.24rc1) + idx := strings.IndexFunc(raw, func(r rune) bool { + return (r < '0' || r > '9') && r != '.' + }) + + if idx != -1 { + raw = raw[:idx] + } + + return raw } func parseGoMod(goMod string) (*modfile.File, error) { diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index fa99bdf0b760..4c4688d7a650 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -83,3 +83,47 @@ func TestIsGoGreaterThanOrEqual(t *testing.T) { }) } } + +func Test_parseGoVersion(t *testing.T) { + testCases := []struct { + desc string + version string + expected string + }{ + { + desc: "empty version", + version: "", + expected: "", + }, + { + desc: "no prefixed version", + version: "1.23.0", + expected: "1.23.0", + }, + { + desc: "semver version", + version: "go1.23.0", + expected: "1.23.0", + }, + { + desc: "family version", + version: "go1.23", + expected: "1.23", + }, + { + desc: "prerelease version", + version: "go1.24rc1", + expected: "1.24", + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + v := parseGoVersion(test.version) + + assert.Equal(t, test.expected, v) + }) + } +}