Skip to content

Commit

Permalink
cmd/go: introduce GOROOT/go.env and move proxy/sumdb config there
Browse files Browse the repository at this point in the history
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 <rsc@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
  • Loading branch information
rsc authored and pull[bot] committed Aug 29, 2023
1 parent 0c9bdb9 commit e39f2da
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
8 changes: 8 additions & 0 deletions 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
45 changes: 37 additions & 8 deletions src/cmd/go/internal/cfg/cfg.go
Expand Up @@ -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" }
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 := ""
Expand Down

0 comments on commit e39f2da

Please sign in to comment.