cmd/goimports: permit complete filename for -srcdir
Updates dominikh/go-mode.el#146 Updates golang/go#7463 (for https://golang.org/cl/23444) Change-Id: Ieb769329531050b803528acce0c50d02786533b6 Reviewed-on: https://go-review.googlesource.com/25140 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
5b59ce8b5f
commit
f3284303b6
|
@ -7,6 +7,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
|
@ -29,7 +30,7 @@ var (
|
||||||
list = flag.Bool("l", false, "list files whose formatting differs from goimport's")
|
list = flag.Bool("l", false, "list files whose formatting differs from goimport's")
|
||||||
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
|
write = flag.Bool("w", false, "write result to (source) file instead of stdout")
|
||||||
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
|
doDiff = flag.Bool("d", false, "display diffs instead of rewriting files")
|
||||||
srcdir = flag.String("srcdir", "", "choose imports as if source code is from `dir`")
|
srcdir = flag.String("srcdir", "", "choose imports as if source code is from `dir`. When operating on a single file, dir may instead be the complete file name.")
|
||||||
verbose = flag.Bool("v", false, "verbose logging")
|
verbose = flag.Bool("v", false, "verbose logging")
|
||||||
|
|
||||||
cpuProfile = flag.String("cpuprofile", "", "CPU profile output")
|
cpuProfile = flag.String("cpuprofile", "", "CPU profile output")
|
||||||
|
@ -67,9 +68,25 @@ func isGoFile(f os.FileInfo) bool {
|
||||||
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
|
||||||
}
|
}
|
||||||
|
|
||||||
func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error {
|
// argumentType is which mode goimports was invoked as.
|
||||||
|
type argumentType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// fromStdin means the user is piping their source into goimports.
|
||||||
|
fromStdin argumentType = iota
|
||||||
|
|
||||||
|
// singleArg is the common case from editors, when goimports is run on
|
||||||
|
// a single file.
|
||||||
|
singleArg
|
||||||
|
|
||||||
|
// multipleArg is when the user ran "goimports file1.go file2.go"
|
||||||
|
// or ran goimports on a directory tree.
|
||||||
|
multipleArg
|
||||||
|
)
|
||||||
|
|
||||||
|
func processFile(filename string, in io.Reader, out io.Writer, argType argumentType) error {
|
||||||
opt := options
|
opt := options
|
||||||
if stdin {
|
if argType == fromStdin {
|
||||||
nopt := *options
|
nopt := *options
|
||||||
nopt.Fragment = true
|
nopt.Fragment = true
|
||||||
opt = &nopt
|
opt = &nopt
|
||||||
|
@ -91,9 +108,30 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
|
||||||
|
|
||||||
target := filename
|
target := filename
|
||||||
if *srcdir != "" {
|
if *srcdir != "" {
|
||||||
// Pretend that file is from *srcdir in order to decide
|
// Determine whether the provided -srcdirc is a directory or file
|
||||||
// visible imports correctly.
|
// and then use it to override the target.
|
||||||
target = filepath.Join(*srcdir, filepath.Base(filename))
|
//
|
||||||
|
// See https://github.com/dominikh/go-mode.el/issues/146
|
||||||
|
if isFile(*srcdir) {
|
||||||
|
if argType == multipleArg {
|
||||||
|
return errors.New("-srcdir value can't be a file when passing multiple arguments or when walking directories")
|
||||||
|
}
|
||||||
|
target = *srcdir
|
||||||
|
} else if argType == singleArg && strings.HasSuffix(*srcdir, ".go") && !isDir(*srcdir) {
|
||||||
|
// For a file which doesn't exist on disk yet, but might shortly.
|
||||||
|
// e.g. user in editor opens $DIR/newfile.go and newfile.go doesn't yet exist on disk.
|
||||||
|
// The goimports on-save hook writes the buffer to a temp file
|
||||||
|
// first and runs goimports before the actual save to newfile.go.
|
||||||
|
// The editor's buffer is named "newfile.go" so that is passed to goimports as:
|
||||||
|
// goimports -srcdir=/gopath/src/pkg/newfile.go /tmp/gofmtXXXXXXXX.go
|
||||||
|
// and then the editor reloads the result from the tmp file and writes
|
||||||
|
// it to newfile.go.
|
||||||
|
target = *srcdir
|
||||||
|
} else {
|
||||||
|
// Pretend that file is from *srcdir in order to decide
|
||||||
|
// visible imports correctly.
|
||||||
|
target = filepath.Join(*srcdir, filepath.Base(filename))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := imports.Process(target, src, opt)
|
res, err := imports.Process(target, src, opt)
|
||||||
|
@ -131,7 +169,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
|
||||||
|
|
||||||
func visitFile(path string, f os.FileInfo, err error) error {
|
func visitFile(path string, f os.FileInfo, err error) error {
|
||||||
if err == nil && isGoFile(f) {
|
if err == nil && isGoFile(f) {
|
||||||
err = processFile(path, nil, os.Stdout, false)
|
err = processFile(path, nil, os.Stdout, multipleArg)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
report(err)
|
report(err)
|
||||||
|
@ -215,12 +253,17 @@ func gofmtMain() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
if err := processFile("<standard input>", os.Stdin, os.Stdout, true); err != nil {
|
if err := processFile("<standard input>", os.Stdin, os.Stdout, fromStdin); err != nil {
|
||||||
report(err)
|
report(err)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
argType := singleArg
|
||||||
|
if len(paths) > 1 {
|
||||||
|
argType = multipleArg
|
||||||
|
}
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
switch dir, err := os.Stat(path); {
|
switch dir, err := os.Stat(path); {
|
||||||
case err != nil:
|
case err != nil:
|
||||||
|
@ -228,7 +271,7 @@ func gofmtMain() {
|
||||||
case dir.IsDir():
|
case dir.IsDir():
|
||||||
walkDir(path)
|
walkDir(path)
|
||||||
default:
|
default:
|
||||||
if err := processFile(path, nil, os.Stdout, false); err != nil {
|
if err := processFile(path, nil, os.Stdout, argType); err != nil {
|
||||||
report(err)
|
report(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,3 +304,15 @@ func diff(b1, b2 []byte) (data []byte, err error) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isFile reports whether name is a file.
|
||||||
|
func isFile(name string) bool {
|
||||||
|
fi, err := os.Stat(name)
|
||||||
|
return err == nil && fi.Mode().IsRegular()
|
||||||
|
}
|
||||||
|
|
||||||
|
// isDir reports whether name is a directory.
|
||||||
|
func isDir(name string) bool {
|
||||||
|
fi, err := os.Stat(name)
|
||||||
|
return err == nil && fi.IsDir()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue