diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/go/internal/work/shell.go | 33 | ||||
| -rw-r--r-- | src/cmd/go/testdata/script/build_output_overwrite.txt | 20 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/cmd/go/internal/work/shell.go b/src/cmd/go/internal/work/shell.go index 284ed26f22..ceff84d81f 100644 --- a/src/cmd/go/internal/work/shell.go +++ b/src/cmd/go/internal/work/shell.go @@ -123,6 +123,11 @@ func (sh *Shell) moveOrCopyFile(dst, src string, perm fs.FileMode, force bool) e 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. @@ -193,16 +198,9 @@ func (sh *Shell) CopyFile(dst, src string, perm fs.FileMode, force bool) error { } 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. @@ -247,6 +245,21 @@ func mayberemovefile(s string) { 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 { diff --git a/src/cmd/go/testdata/script/build_output_overwrite.txt b/src/cmd/go/testdata/script/build_output_overwrite.txt new file mode 100644 index 0000000000..c7b967ccec --- /dev/null +++ b/src/cmd/go/testdata/script/build_output_overwrite.txt @@ -0,0 +1,20 @@ +# 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() {} |
