]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go/internal/cache: squelch cache init warnings when $HOME is /
authorZev Goldstein <Zev.Goldstein@gmail.com>
Mon, 9 Jul 2018 02:31:28 +0000 (22:31 -0400)
committerIan Lance Taylor <iant@golang.org>
Tue, 17 Jul 2018 05:17:31 +0000 (05:17 +0000)
Docker sets $HOME to / when running with a UID that doesn't exist within
the container.  This not  uncommon on CI servers.

Fixes #26280

Change-Id: Ic7ff62b41403fe6e7c0cef12814667ef73f6c954
Reviewed-on: https://go-review.googlesource.com/122487
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/internal/cache/default.go
src/cmd/go/internal/cache/default_unix_test.go [new file with mode: 0644]

index 97283762258d659c0a6fcacc5d9c32fe80eebc88..02fc1e896f74d80b5a1564d16ce778b425a3cdb3 100644 (file)
@@ -35,12 +35,14 @@ 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 := DefaultDir()
+       dir, showWarnings := defaultDir()
        if dir == "off" {
                return
        }
        if err := os.MkdirAll(dir, 0777); err != nil {
-               fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+               if showWarnings {
+                       fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+               }
                return
        }
        if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
@@ -50,7 +52,9 @@ func initDefaultCache() {
 
        c, err := Open(dir)
        if err != nil {
-               fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+               if showWarnings {
+                       fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
+               }
                return
        }
        defaultCache = c
@@ -59,14 +63,24 @@ 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
+               return dir, true
        }
 
        // Compute default location.
        // TODO(rsc): This code belongs somewhere else,
        // like maybe ioutil.CacheDir or os.CacheDir.
+       showWarnings := true
        switch runtime.GOOS {
        case "windows":
                dir = os.Getenv("LocalAppData")
@@ -76,20 +90,20 @@ func DefaultDir() string {
                        dir = os.Getenv("AppData")
                }
                if dir == "" {
-                       return "off"
+                       return "off", true
                }
 
        case "darwin":
                dir = os.Getenv("HOME")
                if dir == "" {
-                       return "off"
+                       return "off", true
                }
                dir += "/Library/Caches"
 
        case "plan9":
                dir = os.Getenv("home")
                if dir == "" {
-                       return "off"
+                       return "off", true
                }
                // Plan 9 has no established per-user cache directory,
                // but $home/lib/xyz is the usual equivalent of $HOME/.xyz on Unix.
@@ -101,10 +115,15 @@ func DefaultDir() string {
                if dir == "" {
                        dir = os.Getenv("HOME")
                        if dir == "" {
-                               return "off"
+                               return "off", true
+                       }
+                       if dir == "/" {
+                               // probably docker run with -u flag
+                               // https://golang.org/issue/26280
+                               showWarnings = false
                        }
                        dir += "/.cache"
                }
        }
-       return filepath.Join(dir, "go-build")
+       return filepath.Join(dir, "go-build"), showWarnings
 }
diff --git a/src/cmd/go/internal/cache/default_unix_test.go b/src/cmd/go/internal/cache/default_unix_test.go
new file mode 100644 (file)
index 0000000..a207497
--- /dev/null
@@ -0,0 +1,67 @@
+// 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 initalization warnings should be squelched when $GOCACHE and $XDG_CACHE_HOME are unset and $HOME is /")
+       }
+}