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.go46
1 files changed, 39 insertions, 7 deletions
diff --git a/src/cmd/go/clean.go b/src/cmd/go/clean.go
index 8345c9af1..16687f72f 100644
--- a/src/cmd/go/clean.go
+++ b/src/cmd/go/clean.go
@@ -137,22 +137,38 @@ func clean(p *Package) {
}
_, elem := filepath.Split(p.Dir)
- allRemove := []string{
- elem,
- elem + ".exe",
- elem + ".test",
- elem + ".test.exe",
+ var allRemove []string
+
+ // Remove dir-named executable only if this is package main.
+ if p.Name == "main" {
+ allRemove = append(allRemove,
+ elem,
+ elem+".exe",
+ )
}
+
+ // Remove package test executables.
+ allRemove = append(allRemove,
+ elem+".test",
+ elem+".test.exe",
+ )
+
+ // Remove a potental executable for each .go file in the directory that
+ // is not part of the directory's package.
for _, dir := range dirs {
name := dir.Name()
if packageFile[name] {
continue
}
if !dir.IsDir() && strings.HasSuffix(name, ".go") {
+ // TODO(adg,rsc): check that this .go file is actually
+ // in "package main", and therefore capable of building
+ // to an executable file.
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, " "))
}
@@ -221,7 +237,23 @@ func clean(p *Package) {
// removeFile tries to remove file f, if error other than file doesn't exist
// occurs, it will report the error.
func removeFile(f string) {
- if err := os.Remove(f); err != nil && !os.IsNotExist(err) {
- errorf("go clean: %v", err)
+ err := os.Remove(f)
+ if err == nil || os.IsNotExist(err) {
+ return
+ }
+ // Windows does not allow deletion of a binary file while it is executing.
+ if toolIsWindows {
+ // Remove lingering ~ file from last attempt.
+ if _, err2 := os.Stat(f + "~"); err2 == nil {
+ os.Remove(f + "~")
+ }
+ // Try to move it out of the way. If the move fails,
+ // which is likely, we'll try again the
+ // next time we do an install of this binary.
+ if err2 := os.Rename(f, f+"~"); err2 == nil {
+ os.Remove(f + "~")
+ return
+ }
}
+ errorf("go clean: %v", err)
}