diff options
author | Robert Griesemer <gri@golang.org> | 2016-11-09 15:29:41 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2016-11-10 00:30:18 +0000 |
commit | b188b4cc110261a004674df5a4e209cc4894d314 (patch) | |
tree | 16bd2be699531114409a1fb7199f2bf709671b27 /src/cmd/gofmt/gofmt.go | |
parent | add8028eb9925db0ec9d3d0f95dec65c8cab1d96 (diff) | |
download | go-git-b188b4cc110261a004674df5a4e209cc4894d314.tar.gz |
cmd/gofmt: don't eat source if -w fails
Write output to a temp file first and only upon success
rename that file to source file name.
Fixes #8984.
Change-Id: Ie40e49d2a4eb3c9462fe769ccbf055b4366eceb0
Reviewed-on: https://go-review.googlesource.com/33018
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/gofmt/gofmt.go')
-rw-r--r-- | src/cmd/gofmt/gofmt.go | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go index f29b6cb83d..4cf91336a3 100644 --- a/src/cmd/gofmt/gofmt.go +++ b/src/cmd/gofmt/gofmt.go @@ -116,7 +116,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error fmt.Fprintln(out, filename) } if *write { - err = ioutil.WriteFile(filename, res, 0644) + err = writeFile(filename, res, 0644) if err != nil { return err } @@ -235,3 +235,35 @@ func diff(b1, b2 []byte) (data []byte, err error) { return } + +// writeFile is a drop-in replacement for ioutil.WriteFile; +// but writeFile writes data to a temporary file first and +// only upon success renames that file to filename. +// TODO(gri) This can be removed if #17869 is accepted and +// implemented. +func writeFile(filename string, data []byte, perm os.FileMode) error { + // open temp file + f, err := ioutil.TempFile(filepath.Dir(filename), "tmp") + if err != nil { + return err + } + err = f.Chmod(perm) + if err != nil { + return err + } + tmpname := f.Name() + + // write data to temp file + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err1 := f.Close(); err == nil { + err = err1 + } + if err != nil { + return err + } + + return os.Rename(tmpname, filename) +} |