mirror of
https://github.com/golang/go
synced 2024-11-11 22:50:22 -07:00
cmd/go: reject GOCACHE=off when the default cache is initialized
Allow GOCACHE=off only for operations that never actually write anything to the cache (in which case the GOCACHE setting should not matter at all). Fixes #29127 Change-Id: I733d02cd2fbcf3671f5adcfb73522865d131e360 Reviewed-on: https://go-review.googlesource.com/c/153462 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
3ae2c6c52e
commit
862ba63823
@ -91,11 +91,11 @@ Go 1.13 will require macOS 10.11 El Capitan or later.
|
||||
<h3 id="gocache">Build cache requirement</h3>
|
||||
|
||||
<p>
|
||||
The build cache is now required as a step toward eliminating
|
||||
The <a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a> is now
|
||||
required as a step toward eliminating
|
||||
<code>$GOPATH/pkg</code>. Setting the environment variable
|
||||
<code>GOCACHE=off</code> to disable the
|
||||
<a href="/cmd/go/#hdr-Build_and_test_caching">build cache</a>
|
||||
has no effect in Go 1.12.
|
||||
<code>GOCACHE=off</code> will cause <code>go</code> commands that write to the
|
||||
cache to fail.
|
||||
</p>
|
||||
|
||||
<h3 id="binary-only">Binary-only packages</h3>
|
||||
|
2
src/cmd/dist/test.go
vendored
2
src/cmd/dist/test.go
vendored
@ -519,7 +519,6 @@ func (t *tester) registerTests() {
|
||||
}
|
||||
|
||||
// Run `go test fmt` in the moved GOROOT.
|
||||
// Disable GOCACHE because it points back at the old GOROOT.
|
||||
cmd := exec.Command(filepath.Join(moved, "bin", "go"), "test", "fmt")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
@ -529,7 +528,6 @@ func (t *tester) registerTests() {
|
||||
cmd.Env = append(cmd.Env, e)
|
||||
}
|
||||
}
|
||||
cmd.Env = append(cmd.Env, "GOCACHE=off")
|
||||
err := cmd.Run()
|
||||
|
||||
if rerr := os.Rename(moved, goroot); rerr != nil {
|
||||
|
@ -5011,7 +5011,8 @@ func TestExecBuildX(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
tg.setenv("GOCACHE", "off")
|
||||
tg.tempDir("cache")
|
||||
tg.setenv("GOCACHE", tg.path("cache"))
|
||||
|
||||
tg.tempFile("main.go", `package main; import "C"; func main() { print("hello") }`)
|
||||
src := tg.path("main.go")
|
||||
@ -5542,30 +5543,6 @@ func TestTestCacheInputs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoCache(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
t.Skipf("no unwritable directories on %s", runtime.GOOS)
|
||||
}
|
||||
if os.Getuid() == 0 {
|
||||
t.Skip("skipping test because running as root")
|
||||
}
|
||||
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.parallel()
|
||||
tg.tempFile("triv.go", `package main; func main() {}`)
|
||||
tg.must(os.MkdirAll(tg.path("unwritable"), 0555))
|
||||
home := "HOME"
|
||||
if runtime.GOOS == "plan9" {
|
||||
home = "home"
|
||||
}
|
||||
tg.setenv(home, tg.path(filepath.Join("unwritable", "home")))
|
||||
tg.unsetenv("GOCACHE")
|
||||
tg.run("build", "-o", tg.path("triv"), tg.path("triv.go"))
|
||||
tg.grepStderr("disabling cache", "did not disable cache")
|
||||
}
|
||||
|
||||
func TestTestVet(t *testing.T) {
|
||||
tooSlow(t)
|
||||
tg := testgo(t)
|
||||
@ -5715,17 +5692,6 @@ func TestFmtLoadErrors(t *testing.T) {
|
||||
tg.run("fmt", "-n", "exclude")
|
||||
}
|
||||
|
||||
func TestRelativePkgdir(t *testing.T) {
|
||||
tooSlow(t)
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.makeTempdir()
|
||||
tg.setenv("GOCACHE", "off")
|
||||
tg.cd(tg.tempdir)
|
||||
|
||||
tg.run("build", "-i", "-pkgdir=.", "runtime")
|
||||
}
|
||||
|
||||
func TestGoTestMinusN(t *testing.T) {
|
||||
// Intent here is to verify that 'go test -n' works without crashing.
|
||||
// This reuses flag_test.go, but really any test would do.
|
||||
@ -6107,28 +6073,6 @@ func TestDontReportRemoveOfEmptyDir(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 23264.
|
||||
func TestNoRelativeTmpdir(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
|
||||
tg.tempFile("src/a/a.go", `package a`)
|
||||
tg.cd(tg.path("."))
|
||||
tg.must(os.Mkdir("tmp", 0777))
|
||||
|
||||
tg.setenv("GOCACHE", "off")
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
tg.setenv("GOTMPDIR", "tmp")
|
||||
tg.run("build", "-work", "a")
|
||||
tg.grepStderr("WORK=[^t]", "work should be absolute path")
|
||||
|
||||
tg.unsetenv("GOTMPDIR")
|
||||
tg.setenv("TMP", "tmp") // windows
|
||||
tg.setenv("TMPDIR", "tmp") // unix
|
||||
tg.run("build", "-work", "a")
|
||||
tg.grepStderr("WORK=[^t]", "work should be absolute path")
|
||||
}
|
||||
|
||||
// Issue 24704.
|
||||
func TestLinkerTmpDirIsDeleted(t *testing.T) {
|
||||
skipIfGccgo(t, "gccgo does not use cmd/link")
|
||||
|
52
src/cmd/go/internal/cache/default.go
vendored
52
src/cmd/go/internal/cache/default.go
vendored
@ -10,6 +10,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
)
|
||||
|
||||
// Default returns the default cache to use, or nil if no cache should be used.
|
||||
@ -34,15 +36,12 @@ See golang.org to learn more about Go.
|
||||
// initDefaultCache does the work of finding the default cache
|
||||
// the first time Default is called.
|
||||
func initDefaultCache() {
|
||||
dir, showWarnings := defaultDir()
|
||||
dir := DefaultDir()
|
||||
if dir == "off" {
|
||||
return
|
||||
die()
|
||||
}
|
||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
if showWarnings {
|
||||
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
|
||||
}
|
||||
return
|
||||
base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
|
||||
// Best effort.
|
||||
@ -51,10 +50,7 @@ func initDefaultCache() {
|
||||
|
||||
c, err := Open(dir)
|
||||
if err != nil {
|
||||
if showWarnings {
|
||||
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
|
||||
}
|
||||
return
|
||||
base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
|
||||
}
|
||||
defaultCache = c
|
||||
}
|
||||
@ -62,34 +58,26 @@ func initDefaultCache() {
|
||||
// DefaultDir returns the effective GOCACHE setting.
|
||||
// It returns "off" if the cache is disabled.
|
||||
func DefaultDir() string {
|
||||
dir, _ := defaultDir()
|
||||
return dir
|
||||
}
|
||||
|
||||
// defaultDir returns the effective GOCACHE setting.
|
||||
// It returns "off" if the cache is disabled.
|
||||
// The second return value reports whether warnings should
|
||||
// be shown if the cache fails to initialize.
|
||||
func defaultDir() (string, bool) {
|
||||
dir := os.Getenv("GOCACHE")
|
||||
if dir != "" {
|
||||
return dir, true
|
||||
return dir
|
||||
}
|
||||
|
||||
// Compute default location.
|
||||
dir, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
return "off", true
|
||||
return "off"
|
||||
}
|
||||
dir = filepath.Join(dir, "go-build")
|
||||
|
||||
// Do this after filepath.Join, so that the path has been cleaned.
|
||||
showWarnings := true
|
||||
switch dir {
|
||||
case "/.cache/go-build":
|
||||
// probably docker run with -u flag
|
||||
// https://golang.org/issue/26280
|
||||
showWarnings = false
|
||||
}
|
||||
return dir, showWarnings
|
||||
return filepath.Join(dir, "go-build")
|
||||
}
|
||||
|
||||
// die calls base.Fatalf with a message explaining why DefaultDir was "off".
|
||||
func die() {
|
||||
if os.Getenv("GOCACHE") == "off" {
|
||||
base.Fatalf("build cache is disabled by GOCACHE=off, but required as of Go 1.12")
|
||||
}
|
||||
if _, err := os.UserCacheDir(); err != nil {
|
||||
base.Fatalf("build cache is required, but could not be located: %v", err)
|
||||
}
|
||||
panic(fmt.Sprintf("cache.die called unexpectedly with cache.DefaultDir() = %s", DefaultDir()))
|
||||
}
|
||||
|
67
src/cmd/go/internal/cache/default_unix_test.go
vendored
67
src/cmd/go/internal/cache/default_unix_test.go
vendored
@ -1,67 +0,0 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !windows,!darwin,!plan9
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDefaultDir(t *testing.T) {
|
||||
goCacheDir := "/tmp/test-go-cache"
|
||||
xdgCacheDir := "/tmp/test-xdg-cache"
|
||||
homeDir := "/tmp/test-home"
|
||||
|
||||
// undo env changes when finished
|
||||
defer func(GOCACHE, XDG_CACHE_HOME, HOME string) {
|
||||
os.Setenv("GOCACHE", GOCACHE)
|
||||
os.Setenv("XDG_CACHE_HOME", XDG_CACHE_HOME)
|
||||
os.Setenv("HOME", HOME)
|
||||
}(os.Getenv("GOCACHE"), os.Getenv("XDG_CACHE_HOME"), os.Getenv("HOME"))
|
||||
|
||||
os.Setenv("GOCACHE", goCacheDir)
|
||||
os.Setenv("XDG_CACHE_HOME", xdgCacheDir)
|
||||
os.Setenv("HOME", homeDir)
|
||||
|
||||
dir, showWarnings := defaultDir()
|
||||
if dir != goCacheDir {
|
||||
t.Errorf("Cache DefaultDir %q should be $GOCACHE %q", dir, goCacheDir)
|
||||
}
|
||||
if !showWarnings {
|
||||
t.Error("Warnings should be shown when $GOCACHE is set")
|
||||
}
|
||||
|
||||
os.Unsetenv("GOCACHE")
|
||||
dir, showWarnings = defaultDir()
|
||||
if !strings.HasPrefix(dir, xdgCacheDir+"/") {
|
||||
t.Errorf("Cache DefaultDir %q should be under $XDG_CACHE_HOME %q when $GOCACHE is unset", dir, xdgCacheDir)
|
||||
}
|
||||
if !showWarnings {
|
||||
t.Error("Warnings should be shown when $XDG_CACHE_HOME is set")
|
||||
}
|
||||
|
||||
os.Unsetenv("XDG_CACHE_HOME")
|
||||
dir, showWarnings = defaultDir()
|
||||
if !strings.HasPrefix(dir, homeDir+"/.cache/") {
|
||||
t.Errorf("Cache DefaultDir %q should be under $HOME/.cache %q when $GOCACHE and $XDG_CACHE_HOME are unset", dir, homeDir+"/.cache")
|
||||
}
|
||||
if !showWarnings {
|
||||
t.Error("Warnings should be shown when $HOME is not /")
|
||||
}
|
||||
|
||||
os.Unsetenv("HOME")
|
||||
if dir, _ := defaultDir(); dir != "off" {
|
||||
t.Error("Cache not disabled when $GOCACHE, $XDG_CACHE_HOME, and $HOME are unset")
|
||||
}
|
||||
|
||||
os.Setenv("HOME", "/")
|
||||
if _, showWarnings := defaultDir(); showWarnings {
|
||||
// https://golang.org/issue/26280
|
||||
t.Error("Cache initialization warnings should be squelched when $GOCACHE and $XDG_CACHE_HOME are unset and $HOME is /")
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
# Set GOCACHE to a clean directory to ensure that 'go build' has work to report.
|
||||
env GOCACHE=$WORK/gocache
|
||||
|
||||
# Build should use GOTMPDIR if set.
|
||||
env GOTMPDIR=$WORK/my-favorite-tmpdir
|
||||
env GOCACHE=off
|
||||
mkdir $GOTMPDIR
|
||||
go build -work hello.go
|
||||
stderr ^WORK=.*my-favorite-tmpdir
|
||||
@ -8,4 +10,3 @@ stderr ^WORK=.*my-favorite-tmpdir
|
||||
-- hello.go --
|
||||
package main
|
||||
func main() { println("hello") }
|
||||
|
||||
|
19
src/cmd/go/testdata/script/build_nocache.txt
vendored
Normal file
19
src/cmd/go/testdata/script/build_nocache.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Set GOCACHE to a directory that doesn't allow writes.
|
||||
[windows] skip # Does not support unwritable directories.
|
||||
[root] skip # Can write to unwritable directories.
|
||||
|
||||
mkdir $WORK/unwritable/home
|
||||
chmod 0555 $WORK/unwritable/home
|
||||
[!plan9] env HOME=$WORK/unwritable/home
|
||||
[plan9] env home=$WORK/unwritable/home
|
||||
|
||||
env GOCACHE=$WORK/unwritable/home
|
||||
|
||||
# As of Go 1.12, the module cache is required:
|
||||
# failure to write to it should cause builds to fail.
|
||||
! go build -o triv triv.go
|
||||
stderr 'failed to initialize build cache.* permission denied'
|
||||
|
||||
-- triv.go --
|
||||
package main
|
||||
func main() {}
|
7
src/cmd/go/testdata/script/build_relative_pkgdir.txt
vendored
Normal file
7
src/cmd/go/testdata/script/build_relative_pkgdir.txt
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# Regression test for golang.org/issue/21309: accept relative -pkgdir argument.
|
||||
|
||||
[short] skip
|
||||
|
||||
mkdir $WORK/gocache
|
||||
env GOCACHE=$WORK/gocache
|
||||
go build -i -pkgdir=. runtime
|
16
src/cmd/go/testdata/script/build_relative_tmpdir.txt
vendored
Normal file
16
src/cmd/go/testdata/script/build_relative_tmpdir.txt
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# If GOTMPDIR is relative, 'go build' should derive an absolute $WORK directory.
|
||||
cd $WORK
|
||||
mkdir tmp
|
||||
env GOTMPDIR=tmp
|
||||
go build -work a
|
||||
stderr 'WORK=\$WORK' # the test script itself converts the absolute directory back to $WORK
|
||||
|
||||
# Similarly if TMP/TMPDIR is relative.
|
||||
env GOTMPDIR=
|
||||
env TMP=tmp # Windows
|
||||
env TMPDIR=tmp # Unix
|
||||
go build -work a
|
||||
stderr 'WORK=\$WORK'
|
||||
|
||||
-- a/a.go --
|
||||
package a
|
34
src/cmd/go/testdata/script/cache_unix.txt
vendored
Normal file
34
src/cmd/go/testdata/script/cache_unix.txt
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
# Integration test for cache directory calculation (cmd/go/internal/cache).
|
||||
|
||||
[windows] skip
|
||||
[darwin] skip
|
||||
[plan9] skip
|
||||
|
||||
mkdir $WORK/gocache
|
||||
mkdir $WORK/xdg
|
||||
mkdir $WORK/home
|
||||
|
||||
# Set GOCACHE, XDG_CACHE_HOME, and HOME.
|
||||
env GOCACHE=$WORK/gocache
|
||||
env XDG_CACHE_HOME=$WORK/xdg
|
||||
env HOME=$WORK/home
|
||||
|
||||
# With all three set, we should prefer GOCACHE.
|
||||
go env GOCACHE
|
||||
stdout '\$WORK/gocache$'
|
||||
|
||||
# Without GOCACHE, we should prefer XDG_CACHE_HOME over HOME.
|
||||
env GOCACHE=
|
||||
go env GOCACHE
|
||||
stdout '\$WORK/xdg/go-build$$'
|
||||
|
||||
# With only HOME set, we should use $HOME/.cache.
|
||||
env XDG_CACHE_HOME=
|
||||
go env GOCACHE
|
||||
stdout '\$WORK/home/.cache/go-build$'
|
||||
|
||||
# With no guidance from the environment, we must disable the cache, but that
|
||||
# should not cause commands that do not write to the cache to fail.
|
||||
env HOME=
|
||||
go env GOCACHE
|
||||
stdout 'off'
|
Loading…
Reference in New Issue
Block a user