From a2b440239ddb07c52da6833a24125f973ee94c0e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 1 Nov 2017 22:16:24 -0400 Subject: [PATCH] cmd/go: add "go clean -cache" Give users a way to remove their caches. Change-Id: I0b041aa54b318e98605675f168fed54ab9b6fd14 Reviewed-on: https://go-review.googlesource.com/75470 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: David Crawshaw --- src/cmd/dist/deps.go | 9 ++++--- src/cmd/go/alldocs.go | 5 +++- src/cmd/go/internal/clean/clean.go | 42 +++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/cmd/dist/deps.go b/src/cmd/dist/deps.go index 55891d41d2..fa525f0545 100644 --- a/src/cmd/dist/deps.go +++ b/src/cmd/dist/deps.go @@ -112,10 +112,11 @@ var builddeps = map[string][]string{ }, "cmd/go/internal/clean": { - "cmd/go/internal/base", // cmd/go/internal/clean - "cmd/go/internal/cfg", // cmd/go/internal/clean - "cmd/go/internal/load", // cmd/go/internal/clean - "cmd/go/internal/work", // cmd/go/internal/clean + "cmd/go/internal/base", // cmd/go/internal/clean + "cmd/go/internal/cache", // cmd/go/internal/clean + "cmd/go/internal/cfg", // cmd/go/internal/clean + "cmd/go/internal/load", // cmd/go/internal/clean + "cmd/go/internal/work", // cmd/go/internal/clean "fmt", // cmd/go/internal/clean "io/ioutil", // cmd/go/internal/clean "os", // cmd/go/internal/clean diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index 7facbd45a2..a61aba8249 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -162,7 +162,7 @@ // // Usage: // -// go clean [-i] [-r] [-n] [-x] [build flags] [packages] +// go clean [-i] [-r] [-n] [-x] [-cache] [build flags] [packages] // // Clean removes object files from package source directories. // The go command builds most objects in a temporary directory, @@ -200,6 +200,9 @@ // // The -x flag causes clean to print remove commands as it executes them. // +// The -cache flag causes clean to remove the entire go build cache, +// in addition to cleaning specified packages (if any). +// // For more about build flags, see 'go help build'. // // For more about specifying packages, see 'go help packages'. diff --git a/src/cmd/go/internal/clean/clean.go b/src/cmd/go/internal/clean/clean.go index b0688e6221..de0aa01cab 100644 --- a/src/cmd/go/internal/clean/clean.go +++ b/src/cmd/go/internal/clean/clean.go @@ -13,13 +13,14 @@ import ( "strings" "cmd/go/internal/base" + "cmd/go/internal/cache" "cmd/go/internal/cfg" "cmd/go/internal/load" "cmd/go/internal/work" ) var CmdClean = &base.Command{ - UsageLine: "clean [-i] [-r] [-n] [-x] [build flags] [packages]", + UsageLine: "clean [-i] [-r] [-n] [-x] [-cache] [build flags] [packages]", Short: "remove object files", Long: ` Clean removes object files from package source directories. @@ -58,14 +59,20 @@ dependencies of the packages named by the import paths. The -x flag causes clean to print remove commands as it executes them. +The -cache flag causes clean to remove the entire go build cache, +in addition to cleaning specified packages (if any). + For more about build flags, see 'go help build'. For more about specifying packages, see 'go help packages'. `, } -var cleanI bool // clean -i flag -var cleanR bool // clean -r flag +var ( + cleanI bool // clean -i flag + cleanR bool // clean -r flag + cleanCache bool // clean -cache flag +) func init() { // break init cycle @@ -73,6 +80,8 @@ func init() { CmdClean.Flag.BoolVar(&cleanI, "i", false, "") CmdClean.Flag.BoolVar(&cleanR, "r", false, "") + CmdClean.Flag.BoolVar(&cleanCache, "cache", false, "") + // -n and -x are important enough to be // mentioned explicitly in the docs but they // are part of the build flags. @@ -84,6 +93,33 @@ func runClean(cmd *base.Command, args []string) { for _, pkg := range load.PackagesAndErrors(args) { clean(pkg) } + + if cleanCache { + var b work.Builder + b.Print = fmt.Print + dir := cache.DefaultDir() + if dir != "off" { + // Remove the cache subdirectories but not the top cache directory. + // The top cache directory may have been created with special permissions + // and not something that we want to remove. Also, we'd like to preserve + // the access log for future analysis, even if the cache is cleared. + subdirs, _ := filepath.Glob(filepath.Join(dir, "[0-9a-f][0-9a-f]")) + if len(subdirs) > 0 { + if cfg.BuildN || cfg.BuildX { + b.Showcmd("", "rm -r %s", strings.Join(subdirs, " ")) + } + printedErrors := false + for _, d := range subdirs { + // Only print the first error - there may be many. + // This also mimics what os.RemoveAll(dir) would do. + if err := os.RemoveAll(d); err != nil && !printedErrors { + printedErrors = true + base.Errorf("go clean -cache: %v", err) + } + } + } + } + } } var cleaned = map[*load.Package]bool{} -- 2.48.1