Skip to content

Commit 56deebb

Browse files
committed
cmd/go: add clean -modcache
We need an easy way to remove $GOPATH/src/mod, especially since all the directories are marked read-only. Change-Id: Ib9e8e47e50048f55ecc4de0229b06c4a416ac114 Reviewed-on: https://go-review.googlesource.com/124382 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Bryan C. Mills <bcmills@google.com>
1 parent 3067878 commit 56deebb

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/cmd/go/internal/clean/clean.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import (
1717
"cmd/go/internal/cache"
1818
"cmd/go/internal/cfg"
1919
"cmd/go/internal/load"
20+
"cmd/go/internal/modfetch"
2021
"cmd/go/internal/work"
2122
)
2223

2324
var CmdClean = &base.Command{
24-
UsageLine: "clean [-i] [-r] [-n] [-x] [-cache] [-testcache] [build flags] [packages]",
25+
UsageLine: "clean [clean flags] [build flags] [packages]",
2526
Short: "remove object files and cached files",
2627
Long: `
2728
Clean removes object files from package source directories.
@@ -65,6 +66,10 @@ The -cache flag causes clean to remove the entire go build cache.
6566
The -testcache flag causes clean to expire all test results in the
6667
go build cache.
6768
69+
The -modcache flag causes clean to remove the entire module
70+
download cache, including unpacked source code of versioned
71+
dependencies.
72+
6873
For more about build flags, see 'go help build'.
6974
7075
For more about specifying packages, see 'go help packages'.
@@ -75,6 +80,7 @@ var (
7580
cleanI bool // clean -i flag
7681
cleanR bool // clean -r flag
7782
cleanCache bool // clean -cache flag
83+
cleanModcache bool // clean -modcache flag
7884
cleanTestcache bool // clean -testcache flag
7985
)
8086

@@ -85,6 +91,7 @@ func init() {
8591
CmdClean.Flag.BoolVar(&cleanI, "i", false, "")
8692
CmdClean.Flag.BoolVar(&cleanR, "r", false, "")
8793
CmdClean.Flag.BoolVar(&cleanCache, "cache", false, "")
94+
CmdClean.Flag.BoolVar(&cleanModcache, "modcache", false, "")
8895
CmdClean.Flag.BoolVar(&cleanTestcache, "testcache", false, "")
8996

9097
// -n and -x are important enough to be
@@ -138,6 +145,29 @@ func runClean(cmd *base.Command, args []string) {
138145
}
139146
}
140147
}
148+
149+
if cleanModcache {
150+
if modfetch.SrcMod == "" {
151+
base.Fatalf("go clean -modcache: no module cache")
152+
}
153+
if err := removeAll(modfetch.SrcMod); err != nil {
154+
base.Errorf("go clean -modcache: %v", err)
155+
}
156+
}
157+
}
158+
159+
func removeAll(dir string) error {
160+
// Module cache has 0555 directories; make them writable in order to remove content.
161+
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
162+
if err != nil {
163+
return nil // ignore errors walking in file system
164+
}
165+
if info.IsDir() {
166+
os.Chmod(path, 0777)
167+
}
168+
return nil
169+
})
170+
return os.RemoveAll(dir)
141171
}
142172

143173
var cleaned = map[*load.Package]bool{}

src/cmd/go/mod_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,11 @@ func TestModList(t *testing.T) {
10671067
t.Fatalf("%s should be unwritable", filepath.Join(dir, "buggy"))
10681068
}
10691069

1070+
tg.run("clean", "-modcache")
1071+
if _, err = os.Stat(dir); err == nil {
1072+
t.Fatal("clean -modcache did not remove download dir")
1073+
}
1074+
10701075
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
10711076
module x
10721077
require rsc.io/quote v1.5.1

0 commit comments

Comments
 (0)