# We use a simple Go program to report many Go versions. # The program also errors on any command other than "go version", # which saves us having to rebuild main.go many times. go build -o .bin/go$exe ./fakego env PATH=${WORK}/.bin${:}${PATH} # An empty go version. env TOOLCHAIN_GOVERSION='' ! exec garble build stderr 'Go version is too old; please upgrade to go1\.22 or newer' # We should error on a devel version that's too old. # Note that they lacked the "goN.M-" prefix. env TOOLCHAIN_GOVERSION='devel +afb5fca Sun Aug 07 00:00:00 2020 +0000' ! exec garble build stderr 'Go version is too old; please upgrade to go1\.22 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' ! exec garble build stderr 'Go version "devel go1\.15-.*2020.*" is too old; please upgrade to go1\.22' # A current devel version should be fine. # Note that we don't look at devel version timestamps. env GARBLE_TEST_GOVERSION='go1.22' env TOOLCHAIN_GOVERSION='devel go1.22-ad97d204f0 Sun Sep 12 16:46:58 2023 +0000' ! exec garble build stderr 'mocking the real build' # We should error on a stable version that's too old. env TOOLCHAIN_GOVERSION='go1.14' ! exec garble build stderr 'Go version "go1\.14" is too old; please upgrade to go1\.22 or newer' # We should accept a future stable version. # Note that we need to bump the version of Go that supposedly built it, too. env GARBLE_TEST_GOVERSION='go1.28.2' env TOOLCHAIN_GOVERSION='go1.28.2' ! exec garble build stderr 'mocking the real build' # We should accept custom devel strings. env TOOLCHAIN_GOVERSION='devel go1.23-somecustomversion' ! exec garble build stderr 'mocking the real build' # The current toolchain may be older than the one that built garble. env GARBLE_TEST_GOVERSION='go1.23' env TOOLCHAIN_GOVERSION='go1.22.3' ! exec garble build stderr 'mocking the real build' # The current toolchain may be equal to the one that built garble. env GARBLE_TEST_GOVERSION='devel go1.22-6673d5d701 Sun Mar 20 16:05:03 2023 +0000' env TOOLCHAIN_GOVERSION='devel go1.22-6673d5d701 Sun Mar 20 16:05:03 2023 +0000' ! exec garble build stderr 'mocking the real build' # The current toolchain must not be newer than the one that built garble. env GARBLE_TEST_GOVERSION='go1.18' env TOOLCHAIN_GOVERSION='go1.22.1' ! exec garble build stderr 'garble was built with "go1\.18" and can''t be used with the newer "go1\.22\.1"; rebuild ' # We'll error even if the difference is a minor (bugfix) level. # In practice it probably wouldn't matter, but in theory it could still lead to tricky bugs. env GARBLE_TEST_GOVERSION='go1.22.11' env TOOLCHAIN_GOVERSION='go1.22.14' ! exec garble build stderr 'garble was built with "go1\.22\.11" and can''t be used with the newer "go1\.22\.14"; rebuild ' # If garble builds itself and is then used, it won't know what version built it. # As a fallback, we drop the comparison against the toolchain's version. env GARBLE_TEST_GOVERSION='bogus version' env TOOLCHAIN_GOVERSION='go1.22.3' ! exec garble build stderr 'mocking the real build' -- go.mod -- module test/main go 1.22 -- main.go -- package main func main() {} -- fakego/main.go -- package main import ( "encoding/json" "fmt" "os" ) func main() { if len(os.Args) > 0 && os.Args[1] == "env" { enc, _ := json.Marshal(struct{ GOVERSION string } { GOVERSION: os.Getenv("TOOLCHAIN_GOVERSION"), }) fmt.Printf("%s\n", enc) return } fmt.Fprintln(os.Stderr, "mocking the real build") os.Exit(1) }