]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/cache: save more data from DefaultDir
authorBryan C. Mills <bcmills@google.com>
Fri, 14 Dec 2018 21:59:04 +0000 (16:59 -0500)
committerBryan C. Mills <bcmills@google.com>
Sat, 15 Dec 2018 00:17:57 +0000 (00:17 +0000)
cmd/go/main.go sets GOCACHE explicitly, so if we don't save some
metadata about how DefaultDir arrived at its answer we will be unable
to reconstruct it later.

Fixes #29243

Change-Id: Ic8bb859ab045a29c91f6a4527e65aedabf874d53
Reviewed-on: https://go-review.googlesource.com/c/154309
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/cmd/go/internal/cache/default.go
src/cmd/go/testdata/script/build_nocache.txt

index 52a1fc8c7a517a65eb3c8018b8284ff31a005add..f545c147009f247e3dbc25c76efe68940391bc11 100644 (file)
@@ -37,8 +37,11 @@ See golang.org to learn more about Go.
 // the first time Default is called.
 func initDefaultCache() {
        dir := DefaultDir()
-       if dir == "off" {
-               die()
+       if dir == "off" || dir == "" {
+               if defaultDirErr != nil {
+                       base.Fatalf("build cache is required, but could not be located: %v", defaultDirErr)
+               }
+               base.Fatalf("build cache is disabled by GOCACHE=off, but required as of Go 1.12")
        }
        if err := os.MkdirAll(dir, 0777); err != nil {
                base.Fatalf("failed to initialize build cache at %s: %s\n", dir, err)
@@ -55,29 +58,35 @@ func initDefaultCache() {
        defaultCache = c
 }
 
+var (
+       defaultDirOnce sync.Once
+       defaultDir     string
+       defaultDirErr  error
+)
+
 // DefaultDir returns the effective GOCACHE setting.
 // It returns "off" if the cache is disabled.
 func DefaultDir() string {
-       dir := os.Getenv("GOCACHE")
-       if dir != "" {
-               return dir
-       }
+       // Save the result of the first call to DefaultDir for later use in
+       // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that
+       // subprocesses will inherit it, but that means initDefaultCache can't
+       // otherwise distinguish between an explicit "off" and a UserCacheDir error.
 
-       // Compute default location.
-       dir, err := os.UserCacheDir()
-       if err != nil {
-               return "off"
-       }
-       return filepath.Join(dir, "go-build")
-}
+       defaultDirOnce.Do(func() {
+               defaultDir = os.Getenv("GOCACHE")
+               if defaultDir != "" {
+                       return
+               }
 
-// 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()))
+               // Compute default location.
+               dir, err := os.UserCacheDir()
+               if err != nil {
+                       defaultDir = "off"
+                       defaultDirErr = fmt.Errorf("GOCACHE is not defined and %v", err)
+                       return
+               }
+               defaultDir = filepath.Join(dir, "go-build")
+       })
+
+       return defaultDir
 }
index 61ea5c5dbdc51f5c28ed2f212c2d7c5141611e5f..5aa46e0b77378e8c3f74c6a228bd90b73ad54b33 100644 (file)
@@ -1,5 +1,22 @@
-# Set GOCACHE to a directory that doesn't allow writes.
-[windows] skip # Does not support unwritable directories.
+# As of Go 1.12, the module cache is required.
+
+# If none of the variables we use to locate GOCACHE are set, the cache is off
+# and we cannot build.
+env GOCACHE=
+env XDG_CACHE_HOME=
+env HOME=
+[plan9] env home=
+[windows] env LocalAppData=
+! go build -o triv triv.go
+stderr 'build cache is required, but could not be located: GOCACHE is not defined and .*'
+
+# An explicit GOCACHE=off also disables builds.
+env GOCACHE=off
+! go build -o triv triv.go
+stderr 'build cache is disabled by GOCACHE=off'
+
+# If GOCACHE is set to an unwritable directory, we should diagnose it as such.
+[windows] stop # Does not support unwritable directories.
 [root] skip # Can write to unwritable directories.
 
 mkdir $WORK/unwritable/home
@@ -8,9 +25,6 @@ chmod 0555 $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'