From 7aa85e01376d840acc8bb931156d607a00b64a60 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 14 Jan 2023 16:40:22 -0500 Subject: [PATCH] cmd/go: introduce GOROOT/go.env and move proxy/sumdb config there Various Linux distributions edit cmd/go/internal/cfg/cfg.go to change the default settings of GOPROXY and GOSUMDB. Make it possible for them to do this without editing the go command source code by introducing GOROOT/go.env and moving those defaults there. With the upcoming changes for reproducible builds (#24904), this should mean that Linux distributions distribute binaries that are bit-for-bit identical to the Go distribution binaries, even when rebuilding the distribution themselves. Fixes #57179. Change-Id: Ib2ecc61e6d036f97db6fd47dca757c94fdea5629 Reviewed-on: https://go-review.googlesource.com/c/go/+/462198 Auto-Submit: Russ Cox Reviewed-by: Bryan Mills TryBot-Result: Gopher Robot Run-TryBot: Russ Cox --- go.env | 8 ++++++ src/cmd/go/internal/cfg/cfg.go | 45 ++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 go.env diff --git a/go.env b/go.env new file mode 100644 index 0000000000..826192283f --- /dev/null +++ b/go.env @@ -0,0 +1,8 @@ +# This file contains the initial defaults for go command configuration. +# Values set by 'go env -w' and written to the user's go/env file override these. +# The environment overrides everything else. + +# Use the Go module mirror and checksum database by default. +# See https://proxy.golang.org for details. +GOPROXY=https://proxy.golang.org,direct +GOSUMDB=sum.golang.org diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index 3257140515..563335220b 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -179,7 +179,7 @@ func defaultContext() build.Context { } func init() { - SetGOROOT(findGOROOT(), false) + SetGOROOT(Getenv("GOROOT"), false) BuildToolchainCompiler = func() string { return "missing-compiler" } BuildToolchainLinker = func() string { return "missing-linker" } } @@ -303,7 +303,22 @@ func EnvFile() (string, error) { func initEnvCache() { envCache.m = make(map[string]string) - file, _ := EnvFile() + if file, _ := EnvFile(); file != "" { + readEnvFile(file, "user") + } + goroot := findGOROOT(envCache.m["GOROOT"]) + if goroot != "" { + readEnvFile(filepath.Join(goroot, "go.env"), "GOROOT") + } + + // Save the goroot for func init calling SetGOROOT, + // and also overwrite anything that might have been in go.env. + // It makes no sense for GOROOT/go.env to specify + // a different GOROOT. + envCache.m["GOROOT"] = goroot +} + +func readEnvFile(file string, source string) { if file == "" { return } @@ -325,13 +340,21 @@ func initEnvCache() { i = bytes.IndexByte(line, '=') if i < 0 || line[0] < 'A' || 'Z' < line[0] { // Line is missing = (or empty) or a comment or not a valid env name. Ignore. - // (This should not happen, since the file should be maintained almost + // This should not happen in the user file, since the file should be maintained almost // exclusively by "go env -w", but better to silently ignore than to make // the go command unusable just because somehow the env file has - // gotten corrupted.) + // gotten corrupted. + // In the GOROOT/go.env file, we expect comments. continue } key, val := line[:i], line[i+1:] + + if source == "GOROOT" { + // In the GOROOT/go.env file, do not overwrite fields loaded from the user's go/env file. + if _, ok := envCache.m[string(key)]; ok { + continue + } + } envCache.m[string(key)] = string(val) } } @@ -383,8 +406,8 @@ var ( GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64)) GOWASM = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM)) - GOPROXY = envOr("GOPROXY", "https://proxy.golang.org,direct") - GOSUMDB = envOr("GOSUMDB", "sum.golang.org") + GOPROXY = envOr("GOPROXY", "") + GOSUMDB = envOr("GOSUMDB", "") GOPRIVATE = Getenv("GOPRIVATE") GONOPROXY = envOr("GONOPROXY", GOPRIVATE) GONOSUMDB = envOr("GONOSUMDB", GOPRIVATE) @@ -437,8 +460,14 @@ func envOr(key, def string) string { // with from runtime.GOROOT(). // // There is a copy of this code in x/tools/cmd/godoc/goroot.go. -func findGOROOT() string { - if env := Getenv("GOROOT"); env != "" { +func findGOROOT(env string) string { + if env == "" { + // Not using Getenv because findGOROOT is called + // to find the GOROOT/go.env file. initEnvCache + // has passed in the setting from the user go/env file. + env = os.Getenv("GOROOT") + } + if env != "" { return filepath.Clean(env) } def := ""