1
0
mirror of https://github.com/golang/go synced 2024-09-30 16:18:35 -06:00

refactor/rename: don't make backups; overwrite in place, preserving inode.

This avoids littering the tree, and confusing some editors (e.g. Atom)
that expect the inode number to remain constant.

Change-Id: I2faeda1ed1b01e5e4cc720744ea3c99ab29e7333
Reviewed-on: https://go-review.googlesource.com/7664
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Alan Donovan 2015-03-17 11:17:36 -04:00
parent 782516301f
commit 2206711864

View File

@ -8,6 +8,7 @@
package rename // import "golang.org/x/tools/refactor/rename" package rename // import "golang.org/x/tools/refactor/rename"
import ( import (
"bytes"
"errors" "errors"
"fmt" "fmt"
"go/ast" "go/ast"
@ -15,9 +16,9 @@ import (
"go/format" "go/format"
"go/parser" "go/parser"
"go/token" "go/token"
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -459,48 +460,15 @@ func plural(n int) string {
return "" return ""
} }
func writeFile(name string, fset *token.FileSet, f *ast.File, mode os.FileMode) error { var rewriteFile = func(fset *token.FileSet, f *ast.File, filename string) (err error) {
out, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
// assume error includes the filename
return fmt.Errorf("failed to open file: %s", err)
}
// Oddly, os.OpenFile doesn't preserve all the mode bits, hence
// this chmod. (We use 0600 above to avoid a brief
// vulnerability if the user has an insecure umask.)
os.Chmod(name, mode) // ignore error
if err := format.Node(out, fset, f); err != nil {
out.Close() // ignore error
return fmt.Errorf("failed to write file: %s", err)
}
return out.Close()
}
var rewriteFile = func(fset *token.FileSet, f *ast.File, orig string) (err error) {
backup := orig + ".gorename.backup"
// TODO(adonovan): print packages and filenames in a form useful // TODO(adonovan): print packages and filenames in a form useful
// to editors (so they can reload files). // to editors (so they can reload files).
if Verbose { if Verbose {
fmt.Fprintf(os.Stderr, "\t%s\n", orig) fmt.Fprintf(os.Stderr, "\t%s\n", filename)
} }
// save file mode var buf bytes.Buffer
var mode os.FileMode = 0666 if err := format.Node(&buf, fset, f); err != nil {
if fi, err := os.Stat(orig); err == nil { return fmt.Errorf("failed to pretty-print syntax tree: %v", err)
mode = fi.Mode()
} }
if err := os.Rename(orig, backup); err != nil { return ioutil.WriteFile(filename, buf.Bytes(), 0644)
return fmt.Errorf("failed to make backup %s -> %s: %s",
orig, filepath.Base(backup), err)
}
if err := writeFile(orig, fset, f, mode); err != nil {
// Restore the file from the backup.
os.Remove(orig) // ignore error
os.Rename(backup, orig) // ignore error
return err
}
os.Remove(backup) // ignore error
return nil
} }