Skip to content

Commit 0c319ee

Browse files
zevdgianlancetaylor
authored andcommitted
cmd/go/internal/cache: squelch cache init warnings when $HOME is /
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 6e4e294 commit 0c319ee

File tree

2 files changed

+95
-9
lines changed

2 files changed

+95
-9
lines changed

src/cmd/go/internal/cache/default.go

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ See golang.org to learn more about Go.
3535
// initDefaultCache does the work of finding the default cache
3636
// the first time Default is called.
3737
func initDefaultCache() {
38-
dir := DefaultDir()
38+
dir, showWarnings := defaultDir()
3939
if dir == "off" {
4040
return
4141
}
4242
if err := os.MkdirAll(dir, 0777); err != nil {
43-
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
43+
if showWarnings {
44+
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
45+
}
4446
return
4547
}
4648
if _, err := os.Stat(filepath.Join(dir, "README")); err != nil {
@@ -50,7 +52,9 @@ func initDefaultCache() {
5052

5153
c, err := Open(dir)
5254
if err != nil {
53-
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
55+
if showWarnings {
56+
fmt.Fprintf(os.Stderr, "go: disabling cache (%s) due to initialization failure: %s\n", dir, err)
57+
}
5458
return
5559
}
5660
defaultCache = c
@@ -59,14 +63,24 @@ func initDefaultCache() {
5963
// DefaultDir returns the effective GOCACHE setting.
6064
// It returns "off" if the cache is disabled.
6165
func DefaultDir() string {
66+
dir, _ := defaultDir()
67+
return dir
68+
}
69+
70+
// defaultDir returns the effective GOCACHE setting.
71+
// It returns "off" if the cache is disabled.
72+
// The second return value reports whether warnings should
73+
// be shown if the cache fails to initialize.
74+
func defaultDir() (string, bool) {
6275
dir := os.Getenv("GOCACHE")
6376
if dir != "" {
64-
return dir
77+
return dir, true
6578
}
6679

6780
// Compute default location.
6881
// TODO(rsc): This code belongs somewhere else,
6982
// like maybe ioutil.CacheDir or os.CacheDir.
83+
showWarnings := true
7084
switch runtime.GOOS {
7185
case "windows":
7286
dir = os.Getenv("LocalAppData")
@@ -76,20 +90,20 @@ func DefaultDir() string {
7690
dir = os.Getenv("AppData")
7791
}
7892
if dir == "" {
79-
return "off"
93+
return "off", true
8094
}
8195

8296
case "darwin":
8397
dir = os.Getenv("HOME")
8498
if dir == "" {
85-
return "off"
99+
return "off", true
86100
}
87101
dir += "/Library/Caches"
88102

89103
case "plan9":
90104
dir = os.Getenv("home")
91105
if dir == "" {
92-
return "off"
106+
return "off", true
93107
}
94108
// Plan 9 has no established per-user cache directory,
95109
// but $home/lib/xyz is the usual equivalent of $HOME/.xyz on Unix.
@@ -101,10 +115,15 @@ func DefaultDir() string {
101115
if dir == "" {
102116
dir = os.Getenv("HOME")
103117
if dir == "" {
104-
return "off"
118+
return "off", true
119+
}
120+
if dir == "/" {
121+
// probably docker run with -u flag
122+
// https://golang.org/issue/26280
123+
showWarnings = false
105124
}
106125
dir += "/.cache"
107126
}
108127
}
109-
return filepath.Join(dir, "go-build")
128+
return filepath.Join(dir, "go-build"), showWarnings
110129
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2018 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build !windows,!darwin,!plan9
6+
7+
package cache
8+
9+
import (
10+
"os"
11+
"strings"
12+
"testing"
13+
)
14+
15+
func TestDefaultDir(t *testing.T) {
16+
goCacheDir := "/tmp/test-go-cache"
17+
xdgCacheDir := "/tmp/test-xdg-cache"
18+
homeDir := "/tmp/test-home"
19+
20+
// undo env changes when finished
21+
defer func(GOCACHE, XDG_CACHE_HOME, HOME string) {
22+
os.Setenv("GOCACHE", GOCACHE)
23+
os.Setenv("XDG_CACHE_HOME", XDG_CACHE_HOME)
24+
os.Setenv("HOME", HOME)
25+
}(os.Getenv("GOCACHE"), os.Getenv("XDG_CACHE_HOME"), os.Getenv("HOME"))
26+
27+
os.Setenv("GOCACHE", goCacheDir)
28+
os.Setenv("XDG_CACHE_HOME", xdgCacheDir)
29+
os.Setenv("HOME", homeDir)
30+
31+
dir, showWarnings := defaultDir()
32+
if dir != goCacheDir {
33+
t.Errorf("Cache DefaultDir %q should be $GOCACHE %q", dir, goCacheDir)
34+
}
35+
if !showWarnings {
36+
t.Error("Warnings should be shown when $GOCACHE is set")
37+
}
38+
39+
os.Unsetenv("GOCACHE")
40+
dir, showWarnings = defaultDir()
41+
if !strings.HasPrefix(dir, xdgCacheDir+"/") {
42+
t.Errorf("Cache DefaultDir %q should be under $XDG_CACHE_HOME %q when $GOCACHE is unset", dir, xdgCacheDir)
43+
}
44+
if !showWarnings {
45+
t.Error("Warnings should be shown when $XDG_CACHE_HOME is set")
46+
}
47+
48+
os.Unsetenv("XDG_CACHE_HOME")
49+
dir, showWarnings = defaultDir()
50+
if !strings.HasPrefix(dir, homeDir+"/.cache/") {
51+
t.Errorf("Cache DefaultDir %q should be under $HOME/.cache %q when $GOCACHE and $XDG_CACHE_HOME are unset", dir, homeDir+"/.cache")
52+
}
53+
if !showWarnings {
54+
t.Error("Warnings should be shown when $HOME is not /")
55+
}
56+
57+
os.Unsetenv("HOME")
58+
if dir, _ := defaultDir(); dir != "off" {
59+
t.Error("Cache not disabled when $GOCACHE, $XDG_CACHE_HOME, and $HOME are unset")
60+
}
61+
62+
os.Setenv("HOME", "/")
63+
if _, showWarnings := defaultDir(); showWarnings {
64+
// https://golang.org/issue/26280
65+
t.Error("Cache initalization warnings should be squelched when $GOCACHE and $XDG_CACHE_HOME are unset and $HOME is /")
66+
}
67+
}

0 commit comments

Comments
 (0)