main: use go env instead of doing all detection manually

This replaces our own manual detection of various variables (GOROOT,
GOPATH, Go version) with a simple call to `go env`.

If the `go` command is not found:

    error: could not find 'go' command: executable file not found in $PATH

If the Go version is too old:

    error: requires go version 1.18 through 1.20, got go1.17

If the Go tool itself outputs an error (using GOROOT=foobar here):

    go: cannot find GOROOT directory: foobar

This does break the case where `go` wasn't available in $PATH but we
would detect it anyway (via some hardcoded OS-dependent paths). I'm not
sure we want to fix that: I think it's better to tell users "make sure
`go version` prints the right value" than to do some automagic detection
of Go binary locations.
This commit is contained in:
Ayke van Laethem
2023-05-23 15:18:34 +02:00
committed by Ron Evans
parent 46d2696363
commit e075e0591d
5 changed files with 64 additions and 134 deletions
+7 -25
View File
@@ -4,9 +4,6 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"strings"
)
@@ -22,8 +19,8 @@ var (
// GetGorootVersion returns the major and minor version for a given GOROOT path.
// If the goroot cannot be determined, (0, 0) is returned.
func GetGorootVersion(goroot string) (major, minor int, err error) {
s, err := GorootVersionString(goroot)
func GetGorootVersion() (major, minor int, err error) {
s, err := GorootVersionString()
if err != nil {
return 0, 0, err
}
@@ -51,24 +48,9 @@ func GetGorootVersion(goroot string) (major, minor int, err error) {
}
// GorootVersionString returns the version string as reported by the Go
// toolchain for the given GOROOT path. It is usually of the form `go1.x.y` but
// can have some variations (for beta releases, for example).
func GorootVersionString(goroot string) (string, error) {
if data, err := os.ReadFile(filepath.Join(goroot, "VERSION")); err == nil {
return string(data), nil
} else if data, err := os.ReadFile(filepath.Join(
goroot, "src", "internal", "buildcfg", "zbootstrap.go")); err == nil {
r := regexp.MustCompile("const version = `(.*)`")
matches := r.FindSubmatch(data)
if len(matches) != 2 {
return "", errors.New("Invalid go version output:\n" + string(data))
}
return string(matches[1]), nil
} else {
return "", err
}
// toolchain. It is usually of the form `go1.x.y` but can have some variations
// (for beta releases, for example).
func GorootVersionString() (string, error) {
err := readGoEnvVars()
return goEnvVars.GOVERSION, err
}