},
"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
//
// 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,
//
// 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'.
"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.
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
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.
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{}