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>
diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go
index fa5af94..40cb324 100644
--- a/src/cmd/go/internal/clean/clean.go
+++ b/src/cmd/go/internal/clean/clean.go
@@ -17,11 +17,12 @@
"cmd/go/internal/cache"
"cmd/go/internal/cfg"
"cmd/go/internal/load"
+ "cmd/go/internal/modfetch"
"cmd/go/internal/work"
)
var CmdClean = &base.Command{
- UsageLine: "clean [-i] [-r] [-n] [-x] [-cache] [-testcache] [build flags] [packages]",
+ UsageLine: "clean [clean flags] [build flags] [packages]",
Short: "remove object files and cached files",
Long: `
Clean removes object files from package source directories.
@@ -65,6 +66,10 @@
The -testcache flag causes clean to expire all test results in the
go build cache.
+The -modcache flag causes clean to remove the entire module
+download cache, including unpacked source code of versioned
+dependencies.
+
For more about build flags, see 'go help build'.
For more about specifying packages, see 'go help packages'.
@@ -75,6 +80,7 @@
cleanI bool // clean -i flag
cleanR bool // clean -r flag
cleanCache bool // clean -cache flag
+ cleanModcache bool // clean -modcache flag
cleanTestcache bool // clean -testcache flag
)
@@ -85,6 +91,7 @@
CmdClean.Flag.BoolVar(&cleanI, "i", false, "")
CmdClean.Flag.BoolVar(&cleanR, "r", false, "")
CmdClean.Flag.BoolVar(&cleanCache, "cache", false, "")
+ CmdClean.Flag.BoolVar(&cleanModcache, "modcache", false, "")
CmdClean.Flag.BoolVar(&cleanTestcache, "testcache", false, "")
// -n and -x are important enough to be
@@ -138,6 +145,29 @@
}
}
}
+
+ if cleanModcache {
+ if modfetch.SrcMod == "" {
+ base.Fatalf("go clean -modcache: no module cache")
+ }
+ if err := removeAll(modfetch.SrcMod); err != nil {
+ base.Errorf("go clean -modcache: %v", err)
+ }
+ }
+}
+
+func removeAll(dir string) error {
+ // Module cache has 0555 directories; make them writable in order to remove content.
+ filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return nil // ignore errors walking in file system
+ }
+ if info.IsDir() {
+ os.Chmod(path, 0777)
+ }
+ return nil
+ })
+ return os.RemoveAll(dir)
}
var cleaned = map[*load.Package]bool{}
diff --git a/src/cmd/go/mod_test.go b/src/cmd/go/mod_test.go
index a15832f..3e8a010 100644
--- a/src/cmd/go/mod_test.go
+++ b/src/cmd/go/mod_test.go
@@ -1067,6 +1067,11 @@
t.Fatalf("%s should be unwritable", filepath.Join(dir, "buggy"))
}
+ tg.run("clean", "-modcache")
+ if _, err = os.Stat(dir); err == nil {
+ t.Fatal("clean -modcache did not remove download dir")
+ }
+
tg.must(ioutil.WriteFile(tg.path("x/go.mod"), []byte(`
module x
require rsc.io/quote v1.5.1