mirror of
https://github.com/golang/go
synced 2024-11-18 11:04:42 -07:00
imports: add configuration mechanism to exclude directories
Each $GOPATH entry may have a file $GOPATH/src/.goimportsignore which may contain blank lines, #comment lines, or lines naming a directory relative to the configuration file to ignore when scanning. No globbing or regex patterns are allowed. Updates golang/go#16367 (goimports speed) Fixes golang/go#16386 (add mechanism to ignore directories) Change-Id: I8f1a88ae6c4d0ed3075444d70aec3e2228c5ce6a Reviewed-on: https://go-review.googlesource.com/24971 Reviewed-by: Rob Pike <r@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
7c26c99973
commit
ffe4e61c64
@ -27,6 +27,18 @@ For GoSublime, follow the steps described here:
|
||||
|
||||
For other editors, you probably know what to do.
|
||||
|
||||
To exclude directories in your $GOPATH from being scanned for Go
|
||||
files, goimports respects a configuration file at
|
||||
$GOPATH/src/.goimportsignore which may contain blank lines, comment
|
||||
lines (beginning with '#'), or lines naming a directory relative to
|
||||
the configuration file to ignore when scanning. No globbing or regex
|
||||
patterns are allowed. Use the "-v" verbose flag to verify it's
|
||||
working and see what goimports is doing.
|
||||
|
||||
File bugs or feature requests at:
|
||||
|
||||
https://golang.org/issues/new?title=x/tools/cmd/goimports:+
|
||||
|
||||
Happy hacking!
|
||||
|
||||
*/
|
||||
|
@ -5,6 +5,8 @@
|
||||
package imports
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
@ -311,10 +313,47 @@ var visitedSymlinks struct {
|
||||
m map[string]struct{}
|
||||
}
|
||||
|
||||
var ignoredDirs []os.FileInfo
|
||||
|
||||
// populateIgnoredDirs reads an optional config file at <path>/.goimportsignore
|
||||
// of relative directories to ignore when scanning for go files.
|
||||
// The provided path is one of the $GOPATH entries with "src" appended.
|
||||
func populateIgnoredDirs(path string) {
|
||||
slurp, err := ioutil.ReadFile(filepath.Join(path, ".goimportsignore"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
bs := bufio.NewScanner(bytes.NewReader(slurp))
|
||||
for bs.Scan() {
|
||||
line := strings.TrimSpace(bs.Text())
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
if fi, err := os.Stat(filepath.Join(path, line)); err == nil {
|
||||
ignoredDirs = append(ignoredDirs, fi)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func skipDir(fi os.FileInfo) bool {
|
||||
for _, ignoredDir := range ignoredDirs {
|
||||
if os.SameFile(fi, ignoredDir) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// shouldTraverse checks if fi, found in dir, is a directory or a symlink to a directory.
|
||||
// It makes sure symlinks were never visited before to avoid symlink loops.
|
||||
func shouldTraverse(dir string, fi os.FileInfo) bool {
|
||||
if fi.IsDir() {
|
||||
if skipDir(fi) {
|
||||
if Debug {
|
||||
log.Printf("skipping directory %q under %s", fi.Name(), dir)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -382,6 +421,9 @@ func scanGoDirs(goRoot bool) {
|
||||
if isGoroot != goRoot {
|
||||
continue
|
||||
}
|
||||
if !goRoot {
|
||||
populateIgnoredDirs(path)
|
||||
}
|
||||
fsgate.enter()
|
||||
testHookScanDir(path)
|
||||
if Debug {
|
||||
@ -554,7 +596,7 @@ func loadExportsGoPath(expectPackage, dir string) map[string]bool {
|
||||
exportList = append(exportList, k)
|
||||
}
|
||||
sort.Strings(exportList)
|
||||
log.Printf("scanned dir %v (package %v): exports = %v", dir, expectPackage, strings.Join(exportList, ", "))
|
||||
log.Printf("loaded exports in dir %v (package %v): %v", dir, expectPackage, strings.Join(exportList, ", "))
|
||||
}
|
||||
return exports
|
||||
}
|
||||
|
@ -985,6 +985,7 @@ func withEmptyGoPath(fn func()) {
|
||||
scanGoRootOnce = &sync.Once{}
|
||||
scanGoPathOnce = &sync.Once{}
|
||||
dirScan = nil
|
||||
ignoredDirs = nil
|
||||
dirScanMu.Unlock()
|
||||
|
||||
oldGOPATH := build.Default.GOPATH
|
||||
@ -1304,6 +1305,26 @@ func TestImportPathToNameGoPathParse(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestIgnoreConfiguration(t *testing.T) {
|
||||
testConfig{
|
||||
gopathFiles: map[string]string{
|
||||
".goimportsignore": "# comment line\n\n example.net", // tests comment, blank line, whitespace trimming
|
||||
"example.net/pkg/pkg.go": "package pkg\nconst X = 1",
|
||||
"otherwise-longer-so-worse.example.net/foo/pkg/pkg.go": "package pkg\nconst X = 1",
|
||||
},
|
||||
}.test(t, func(t *goimportTest) {
|
||||
const in = "package x\n\nconst _ = pkg.X\n"
|
||||
const want = "package x\n\nimport \"otherwise-longer-so-worse.example.net/foo/pkg\"\n\nconst _ = pkg.X\n"
|
||||
buf, err := Process(t.gopath+"/src/x/x.go", []byte(in), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(buf) != want {
|
||||
t.Errorf("wrong output.\ngot:\n%q\nwant:\n%q\n", buf, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func strSet(ss []string) map[string]bool {
|
||||
m := make(map[string]bool)
|
||||
for _, s := range ss {
|
||||
|
Loading…
Reference in New Issue
Block a user