diff options
Diffstat (limited to 'src/cmd/go/clean.go')
-rw-r--r-- | src/cmd/go/clean.go | 199 |
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) + } + } +} |