return nil
}
+ err := checkDstOverwrite(dst, force)
+ if err != nil {
+ return err
+ }
+
// If we can update the mode and rename to the dst, do it.
// Otherwise fall back to standard copy.
}
defer sf.Close()
- // Be careful about removing/overwriting dst.
- // Do not remove/overwrite if dst exists and is a directory
- // or a non-empty non-object file.
- if fi, err := os.Stat(dst); err == nil {
- if fi.IsDir() {
- return fmt.Errorf("build output %q already exists and is a directory", dst)
- }
- if !force && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(dst) {
- return fmt.Errorf("build output %q already exists and is not an object file", dst)
- }
+ err = checkDstOverwrite(dst, force)
+ if err != nil {
+ return err
}
// On Windows, remove lingering ~ file from last attempt.
os.Remove(s)
}
+// Be careful about removing/overwriting dst.
+// Do not remove/overwrite if dst exists and is a directory
+// or a non-empty non-object file.
+func checkDstOverwrite(dst string, force bool) error {
+ if fi, err := os.Stat(dst); err == nil {
+ if fi.IsDir() {
+ return fmt.Errorf("build output %q already exists and is a directory", dst)
+ }
+ if !force && fi.Mode().IsRegular() && fi.Size() != 0 && !isObject(dst) {
+ return fmt.Errorf("build output %q already exists and is not an object file", dst)
+ }
+ }
+ return nil
+}
+
// writeFile writes the text to file.
func (sh *Shell) writeFile(file string, text []byte) error {
if cfg.BuildN || cfg.BuildX {
--- /dev/null
+# windows executables have the .exe extension and won't overwrite source files
+[GOOS:windows] skip
+
+mkdir out
+env GOTMPDIR=$PWD/out
+
+grep 'this should still exist' foo.go
+
+! go build
+stderr 'already exists and is not an object file'
+
+grep 'this should still exist' foo.go
+
+-- go.mod --
+module foo.go
+
+-- foo.go --
+package main // this should still exist
+
+func main() {}