parse `go env GOVERSION` with go/version directly

We don't need to use a regular expression to find "goN.M" anymore,
as go/version seems to deal with "devel" versions from master just fine.
We can then also stop having two separate fields for the version
of the Go toolchain currently being used.
master
Daniel Martí 4 months ago committed by Paul Scheduikat
parent 33e574685b
commit 9d7c84b0c6

@ -53,13 +53,6 @@ type sharedCacheType struct {
// of the Go tool that the original "go build" invocation did. // of the Go tool that the original "go build" invocation did.
GoCmd string GoCmd string
// GoVersion is a version of the Go toolchain currently being used,
// as reported by "go env GOVERSION" and compatible with go/version.
// Note that the version of Go that built the garble binary might be newer.
// Also note that a devel version like "go1.22-231f290e51" is
// currently represented as "go1.22", as the suffix is ignored by go/version.
GoVersion string
// Filled directly from "go env". // Filled directly from "go env".
// Keep in sync with fetchGoEnv. // Keep in sync with fetchGoEnv.
GoEnv struct { GoEnv struct {

@ -539,40 +539,35 @@ func goVersionOK() bool {
unsupportedGo = "go1.26" // the first major version we don't support unsupportedGo = "go1.26" // the first major version we don't support
) )
// rxVersion looks for a version like "go1.2" or "go1.2.3" in `go env GOVERSION`. toolchainVersion := sharedCache.GoEnv.GOVERSION
rxVersion := regexp.MustCompile(`go\d+\.\d+(?:\.\d+)?`) if toolchainVersion == "" {
toolchainVersionFull := sharedCache.GoEnv.GOVERSION
sharedCache.GoVersion = rxVersion.FindString(toolchainVersionFull)
if sharedCache.GoVersion == "" {
// Go 1.15.x and older did not have GOVERSION yet; they are too old anyway. // Go 1.15.x and older did not have GOVERSION yet; they are too old anyway.
fmt.Fprintf(os.Stderr, "Go version is too old; please upgrade to %s or newer\n", minGoVersion) fmt.Fprintf(os.Stderr, "Go version is too old; please upgrade to %s or newer\n", minGoVersion)
return false return false
} }
if version.Compare(sharedCache.GoVersion, minGoVersion) < 0 { if version.Compare(toolchainVersion, minGoVersion) < 0 {
fmt.Fprintf(os.Stderr, "Go version %q is too old; please upgrade to %s or newer\n", toolchainVersionFull, minGoVersion) fmt.Fprintf(os.Stderr, "Go version %q is too old; please upgrade to %s or newer\n", toolchainVersion, minGoVersion)
return false return false
} }
if version.Compare(sharedCache.GoVersion, unsupportedGo) >= 0 { if version.Compare(toolchainVersion, unsupportedGo) >= 0 {
fmt.Fprintf(os.Stderr, "Go version %q is too new; Go linker patches aren't available for %s or later yet\n", toolchainVersionFull, unsupportedGo) fmt.Fprintf(os.Stderr, "Go version %q is too new; Go linker patches aren't available for %s or later yet\n", toolchainVersion, unsupportedGo)
return false return false
} }
// Ensure that the version of Go that built the garble binary is equal or // Ensure that the version of Go that built the garble binary is equal or
// newer than cache.GoVersionSemver. // newer than cache.GoVersionSemver.
builtVersionFull := cmp.Or(os.Getenv("GARBLE_TEST_GOVERSION"), runtime.Version()) builtVersion := cmp.Or(os.Getenv("GARBLE_TEST_GOVERSION"), runtime.Version())
builtVersion := rxVersion.FindString(builtVersionFull) if !version.IsValid(builtVersion) {
if builtVersion == "" {
// If garble built itself, we don't know what Go version was used. // If garble built itself, we don't know what Go version was used.
// Fall back to not performing the check against the toolchain version. // Fall back to not performing the check against the toolchain version.
return true return true
} }
if version.Compare(builtVersion, sharedCache.GoVersion) < 0 { if version.Compare(builtVersion, toolchainVersion) < 0 {
fmt.Fprintf(os.Stderr, ` fmt.Fprintf(os.Stderr, `
garble was built with %q and can't be used with the newer %q; rebuild it with a command like: garble was built with %q and can't be used with the newer %q; rebuild it with a command like:
go install mvdan.cc/garble@latest go install mvdan.cc/garble@latest
`[1:], builtVersionFull, toolchainVersionFull) `[1:], builtVersion, toolchainVersion)
return false return false
} }

@ -9,13 +9,12 @@ env TOOLCHAIN_GOVERSION=''
! exec garble build ! exec garble build
stderr 'Go version is too old; please upgrade to go1\.25\.0 or newer' stderr 'Go version is too old; please upgrade to go1\.25\.0 or newer'
# We should error on a devel version that's too old. # We should error on a devel version that's too old;
# Note that they lacked the "goN.M-" prefix. # note that they started with the string "devel",
# and very old ones didn't even have "goN.M" in them.
env TOOLCHAIN_GOVERSION='devel +afb5fca Sun Aug 07 00:00:00 2020 +0000' env TOOLCHAIN_GOVERSION='devel +afb5fca Sun Aug 07 00:00:00 2020 +0000'
! exec garble build ! exec garble build
stderr 'Go version is too old; please upgrade to go1\.25\.0 or newer' stderr 'Go version "devel \+afb5.*2020.*" is too old; please upgrade to go1\.25\.0 or newer'
# Another form of old version; with an old "goN.M-" prefix.
env TOOLCHAIN_GOVERSION='devel go1.15-afb5fca Sun Aug 07 00:00:00 2020 +0000' env TOOLCHAIN_GOVERSION='devel go1.15-afb5fca Sun Aug 07 00:00:00 2020 +0000'
! exec garble build ! exec garble build
stderr 'Go version "devel go1\.15-.*2020.*" is too old; please upgrade to go1\.25\.0 or newer' stderr 'Go version "devel go1\.15-.*2020.*" is too old; please upgrade to go1\.25\.0 or newer'
@ -23,8 +22,8 @@ stderr 'Go version "devel go1\.15-.*2020.*" is too old; please upgrade to go1\.2
# A current devel version should be fine. # A current devel version should be fine.
# Note that we don't look at devel version timestamps. # Note that we don't look at devel version timestamps.
env GARBLE_TEST_GOVERSION='go1.25.0' env GARBLE_TEST_GOVERSION='go1.25.0'
# TODO: temporarily disabled while we do not support tip. # TODO: we do not currently bother with supporting tip.
# env TOOLCHAIN_GOVERSION='devel go1.24-ad97d204f0 Sun Sep 12 16:46:58 2023 +0000' # env TOOLCHAIN_GOVERSION='go version go1.26-devel_36863d6194 2025-10-17 01:07:59 -0700 linux/amd64'
# ! exec garble build # ! exec garble build
# stderr 'mocking the real build' # stderr 'mocking the real build'
@ -41,7 +40,7 @@ env TOOLCHAIN_GOVERSION='go1.28.2'
stderr 'Go version "go1\.28\.2" is too new; Go linker patches aren''t available for go1\.26 or later yet' stderr 'Go version "go1\.28\.2" is too new; Go linker patches aren''t available for go1\.26 or later yet'
# We should accept custom devel strings. # We should accept custom devel strings.
env TOOLCHAIN_GOVERSION='devel go1.25.0-somecustomversion' env TOOLCHAIN_GOVERSION='go1.25.0-somecustomversion'
! exec garble build ! exec garble build
stderr 'mocking the real build' stderr 'mocking the real build'

Loading…
Cancel
Save