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>
This commit is contained in:
Russ Cox 2018-07-16 21:37:44 -04:00
parent 30678788b2
commit 56deebb3e4
2 changed files with 36 additions and 1 deletions

View file

@ -17,11 +17,12 @@ import (
"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 -cache flag causes clean to remove the entire go build cache.
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 @@ var (
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 @@ func init() {
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 @@ func runClean(cmd *base.Command, args []string) {
}
}
}
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{}

View file

@ -1067,6 +1067,11 @@ func TestModList(t *testing.T) {
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