summaryrefslogtreecommitdiff
path: root/src/cmd/go/clean.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/clean.go')
-rw-r--r--src/cmd/go/clean.go199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/cmd/go/clean.go b/src/cmd/go/clean.go
new file mode 100644
index 000000000..773951826
--- /dev/null
+++ b/src/cmd/go/clean.go
@@ -0,0 +1,199 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+var cmdClean = &Command{
+ UsageLine: "clean [-i] [-r] [-n] [-x] [packages]",
+ Short: "remove object files",
+ Long: `
+Clean removes object files from package source directories.
+The go command builds most objects in a temporary directory,
+so go clean is mainly concerned with object files left by other
+tools or by manual invocations of go build.
+
+Specifically, clean removes the following files from each of the
+source directories corresponding to the import paths:
+
+ _obj/ old object directory, left from Makefiles
+ _test/ old test directory, left from Makefiles
+ _testmain.go old gotest file, left from Makefiles
+ test.out old test log, left from Makefiles
+ build.out old test log, left from Makefiles
+ *.[568ao] object files, left from Makefiles
+
+ DIR(.exe) from go build
+ DIR.test(.exe) from go test -c
+ MAINFILE(.exe) from go build MAINFILE.go
+
+In the list, DIR represents the final path element of the
+directory, and MAINFILE is the base name of any Go source
+file in the directory that is not included when building
+the package.
+
+The -i flag causes clean to remove the corresponding installed
+archive or binary (what 'go install' would create).
+
+The -n flag causes clean to print the remove commands it would execute,
+but not run them.
+
+The -r flag causes clean to be applied recursively to all the
+dependencies of the packages named by the import paths.
+
+The -x flag causes clean to print remove commands as it executes them.
+
+For more about specifying packages, see 'go help packages'.
+ `,
+}
+
+var cleanI bool // clean -i flag
+var cleanN bool // clean -n flag
+var cleanR bool // clean -r flag
+var cleanX bool // clean -x flag
+
+func init() {
+ // break init cycle
+ cmdClean.Run = runClean
+
+ cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
+ cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
+ cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
+ cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
+}
+
+func runClean(cmd *Command, args []string) {
+ for _, pkg := range packagesAndErrors(args) {
+ clean(pkg)
+ }
+}
+
+var cleaned = map[*Package]bool{}
+
+// TODO: These are dregs left by Makefile-based builds.
+// Eventually, can stop deleting these.
+var cleanDir = map[string]bool{
+ "_test": true,
+ "_obj": true,
+}
+
+var cleanFile = map[string]bool{
+ "_testmain.go": true,
+ "test.out": true,
+ "build.out": true,
+ "a.out": true,
+}
+
+var cleanExt = map[string]bool{
+ ".5": true,
+ ".6": true,
+ ".8": true,
+ ".a": true,
+ ".o": true,
+}
+
+func clean(p *Package) {
+ if cleaned[p] {
+ return
+ }
+ if p.Dir == "" {
+ errorf("can't load package: %v", p.Error)
+ return
+ }
+ dirs, err := ioutil.ReadDir(p.Dir)
+ if err != nil {
+ errorf("go clean %s: %v", p.Dir, err)
+ return
+ }
+
+ var b builder
+ b.print = fmt.Print
+
+ packageFile := map[string]bool{}
+ if p.Name != "main" {
+ // Record which files are not in package main.
+ // The others are.
+ keep := func(list []string) {
+ for _, f := range list {
+ packageFile[f] = true
+ }
+ }
+ keep(p.GoFiles)
+ keep(p.CgoFiles)
+ keep(p.TestGoFiles)
+ keep(p.XTestGoFiles)
+ }
+
+ _, elem := filepath.Split(p.Dir)
+ allRemove := []string{
+ elem,
+ elem + ".exe",
+ elem + ".test",
+ elem + ".test.exe",
+ }
+ for _, dir := range dirs {
+ name := dir.Name()
+ if packageFile[name] {
+ continue
+ }
+ if !dir.IsDir() && strings.HasSuffix(name, ".go") {
+ base := name[:len(name)-len(".go")]
+ allRemove = append(allRemove, base, base+".exe")
+ }
+ }
+ if cleanN || cleanX {
+ b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
+ }
+
+ toRemove := map[string]bool{}
+ for _, name := range allRemove {
+ toRemove[name] = true
+ }
+ for _, dir := range dirs {
+ name := dir.Name()
+ if dir.IsDir() {
+ // TODO: Remove once Makefiles are forgotten.
+ if cleanDir[name] {
+ if cleanN || cleanX {
+ b.showcmd(p.Dir, "rm -r %s", name)
+ if cleanN {
+ continue
+ }
+ }
+ os.RemoveAll(filepath.Join(p.Dir, name))
+ }
+ continue
+ }
+
+ if cleanN {
+ continue
+ }
+
+ if cleanFile[name] || cleanExt[filepath.Ext(name)] || toRemove[name] {
+ os.Remove(filepath.Join(p.Dir, name))
+ }
+ }
+
+ if cleanI && p.target != "" {
+ if cleanN || cleanX {
+ b.showcmd("", "rm -f %s", p.target)
+ }
+ if !cleanN {
+ os.Remove(p.target)
+ }
+ }
+
+ if cleanR {
+ for _, p1 := range p.imports {
+ clean(p1)
+ }
+ }
+}