1
0
mirror of https://github.com/golang/go synced 2024-11-26 03:17:57 -07:00

all: update to use filepath.WalkDir instead of filepath.Walk

Now that filepath.WalkDir is available, it is more efficient
and should be used in place of filepath.Walk.
Update the tree to reflect best practices.

As usual, the code compiled with Go 1.4 during bootstrap is excluded.
(In this CL, that's only cmd/dist.)

For #42027.

Change-Id: Ib0f7b1e43e50b789052f9835a63ced701d8c411c
Reviewed-on: https://go-review.googlesource.com/c/go/+/267719
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Russ Cox 2020-11-04 18:20:17 -05:00
parent 0433845ad1
commit c32140fa94
17 changed files with 65 additions and 45 deletions

View File

@ -52,6 +52,7 @@ import (
"go/types" "go/types"
"internal/testenv" "internal/testenv"
"io" "io"
"io/fs"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -89,7 +90,7 @@ func TestFormats(t *testing.T) {
testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
// process all directories // process all directories
filepath.Walk(".", func(path string, info os.FileInfo, err error) error { filepath.WalkDir(".", func(path string, info fs.DirEntry, err error) error {
if info.IsDir() { if info.IsDir() {
if info.Name() == "testdata" { if info.Name() == "testdata" {
return filepath.SkipDir return filepath.SkipDir

View File

@ -1509,6 +1509,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) {
} }
gocacheSubdir, _ := filepath.Rel(dir, gocache) gocacheSubdir, _ := filepath.Rel(dir, gocache)
// Note: Can't use WalkDir here, because this has to compile with Go 1.4.
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if suffix := strings.TrimPrefix(path, dir+string(filepath.Separator)); suffix != "" { if suffix := strings.TrimPrefix(path, dir+string(filepath.Separator)); suffix != "" {
if suffix == gocacheSubdir { if suffix == gocacheSubdir {

View File

@ -234,10 +234,10 @@ func report(err error) {
} }
func walkDir(path string) { func walkDir(path string) {
filepath.Walk(path, visitFile) filepath.WalkDir(path, visitFile)
} }
func visitFile(path string, f fs.FileInfo, err error) error { func visitFile(path string, f fs.DirEntry, err error) error {
if err == nil && isGoFile(f) { if err == nil && isGoFile(f) {
err = processFile(path, false) err = processFile(path, false)
} }
@ -247,7 +247,7 @@ func visitFile(path string, f fs.FileInfo, err error) error {
return nil return nil
} }
func isGoFile(f fs.FileInfo) bool { func isGoFile(f fs.DirEntry) bool {
// ignore non-Go files // ignore non-Go files
name := f.Name() name := f.Name()
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")

View File

@ -774,7 +774,7 @@ func (tg *testgoData) cleanup() {
func removeAll(dir string) error { func removeAll(dir string) error {
// module cache has 0444 directories; // module cache has 0444 directories;
// make them writable in order to remove content. // make them writable in order to remove content.
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
// chmod not only directories, but also things that we couldn't even stat // chmod not only directories, but also things that we couldn't even stat
// due to permission errors: they may also be unreadable directories. // due to permission errors: they may also be unreadable directories.
if err != nil || info.IsDir() { if err != nil || info.IsDir() {
@ -820,8 +820,8 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
} { } {
srcdir := filepath.Join(testGOROOT, copydir) srcdir := filepath.Join(testGOROOT, copydir)
tg.tempDir(filepath.Join("goroot", copydir)) tg.tempDir(filepath.Join("goroot", copydir))
err := filepath.Walk(srcdir, err := filepath.WalkDir(srcdir,
func(path string, info fs.FileInfo, err error) error { func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -838,9 +838,6 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
return err return err
} }
tg.tempFile(dest, string(data)) tg.tempFile(dest, string(data))
if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil {
return err
}
return nil return nil
}) })
if err != nil { if err != nil {

View File

@ -318,9 +318,10 @@ func makeDirsReadOnly(dir string) {
mode fs.FileMode mode fs.FileMode
} }
var dirs []pathMode // in lexical order var dirs []pathMode // in lexical order
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if err == nil && info.Mode()&0222 != 0 { if err == nil && d.IsDir() {
if info.IsDir() { info, err := d.Info()
if err == nil && info.Mode()&0222 != 0 {
dirs = append(dirs, pathMode{path, info.Mode()}) dirs = append(dirs, pathMode{path, info.Mode()})
} }
} }
@ -337,7 +338,7 @@ func makeDirsReadOnly(dir string) {
// any permission changes needed to do so. // any permission changes needed to do so.
func RemoveAll(dir string) error { func RemoveAll(dir string) error {
// Module cache has 0555 directories; make them writable in order to remove content. // Module cache has 0555 directories; make them writable in order to remove content.
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return nil // ignore errors walking in file system return nil // ignore errors walking in file system
} }

View File

@ -88,8 +88,15 @@ func runVersion(ctx context.Context, cmd *base.Command, args []string) {
// scanDir scans a directory for executables to run scanFile on. // scanDir scans a directory for executables to run scanFile on.
func scanDir(dir string) { func scanDir(dir string) {
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if info.Mode().IsRegular() || info.Mode()&fs.ModeSymlink != 0 { if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 {
info, err := d.Info()
if err != nil {
if *versionV {
fmt.Fprintf(os.Stderr, "%s: %v\n", path, err)
}
return nil
}
scanFile(path, info, *versionV) scanFile(path, info, *versionV)
} }
return nil return nil
@ -120,6 +127,7 @@ func scanFile(file string, info fs.FileInfo, mustPrint bool) {
} }
info = i info = i
} }
if !isExe(file, info) { if !isExe(file, info) {
if mustPrint { if mustPrint {
fmt.Fprintf(os.Stderr, "%s: not executable file\n", file) fmt.Fprintf(os.Stderr, "%s: not executable file\n", file)

View File

@ -122,8 +122,8 @@ func main() {
{Name: ".info", Data: info}, {Name: ".info", Data: info},
} }
dir = filepath.Clean(dir) dir = filepath.Clean(dir)
err = filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
if !info.Mode().IsRegular() { if !info.Type().IsRegular() {
return nil return nil
} }
name := info.Name() name := info.Name()

View File

@ -49,7 +49,7 @@ func main() {
a := new(txtar.Archive) a := new(txtar.Archive)
dir = filepath.Clean(dir) dir = filepath.Clean(dir)
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
if path == dir { if path == dir {
return nil return nil
} }
@ -60,7 +60,7 @@ func main() {
} }
return nil return nil
} }
if !info.Mode().IsRegular() { if !info.Type().IsRegular() {
return nil return nil
} }
data, err := ioutil.ReadFile(path) data, err := ioutil.ReadFile(path)

View File

@ -74,7 +74,7 @@ func initParserMode() {
} }
} }
func isGoFile(f fs.FileInfo) bool { func isGoFile(f fs.DirEntry) bool {
// ignore non-Go files // ignore non-Go files
name := f.Name() name := f.Name()
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go") return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")
@ -164,7 +164,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
return err return err
} }
func visitFile(path string, f fs.FileInfo, err error) error { func visitFile(path string, f fs.DirEntry, 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, false)
} }
@ -177,7 +177,7 @@ func visitFile(path string, f fs.FileInfo, err error) error {
} }
func walkDir(path string) { func walkDir(path string) {
filepath.Walk(path, visitFile) filepath.WalkDir(path, visitFile)
} }
func main() { func main() {

View File

@ -108,12 +108,12 @@ func testFiles(t *testing.T, filenames <-chan string, done chan<- int) {
func genFilenames(t *testing.T, filenames chan<- string) { func genFilenames(t *testing.T, filenames chan<- string) {
defer close(filenames) defer close(filenames)
handleFile := func(filename string, fi fs.FileInfo, err error) error { handleFile := func(filename string, d fs.DirEntry, err error) error {
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return nil return nil
} }
if isGoFile(fi) { if isGoFile(d) {
filenames <- filename filenames <- filename
nfiles++ nfiles++
} }
@ -124,13 +124,13 @@ func genFilenames(t *testing.T, filenames chan<- string) {
if *files != "" { if *files != "" {
for _, filename := range strings.Split(*files, ",") { for _, filename := range strings.Split(*files, ",") {
fi, err := os.Stat(filename) fi, err := os.Stat(filename)
handleFile(filename, fi, err) handleFile(filename, &statDirEntry{fi}, err)
} }
return // ignore files under -root return // ignore files under -root
} }
// otherwise, test all Go files under *root // otherwise, test all Go files under *root
filepath.Walk(*root, handleFile) filepath.WalkDir(*root, handleFile)
} }
func TestAll(t *testing.T) { func TestAll(t *testing.T) {
@ -164,3 +164,12 @@ func TestAll(t *testing.T) {
fmt.Printf("processed %d files\n", nfiles) fmt.Printf("processed %d files\n", nfiles)
} }
} }
type statDirEntry struct {
info fs.FileInfo
}
func (d *statDirEntry) Name() string { return d.info.Name() }
func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
func (d *statDirEntry) Type() fs.FileMode { return d.info.Mode().Type() }
func (d *statDirEntry) Info() (fs.FileInfo, error) { return d.info, nil }

View File

@ -33,7 +33,7 @@ func findGorootModules(t *testing.T) []gorootModule {
goBin := testenv.GoToolPath(t) goBin := testenv.GoToolPath(t)
goroot.once.Do(func() { goroot.once.Do(func() {
goroot.err = filepath.Walk(runtime.GOROOT(), func(path string, info fs.FileInfo, err error) error { goroot.err = filepath.WalkDir(runtime.GOROOT(), func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }

View File

@ -31,7 +31,7 @@ func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
t.Fatal("error evaluating GOROOT: ", err) t.Fatal("error evaluating GOROOT: ", err)
} }
var files []string var files []string
err = filepath.Walk(goroot, func(path string, info fs.FileInfo, err error) error { err = filepath.WalkDir(goroot, func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }

View File

@ -510,8 +510,8 @@ func listStdPkgs(goroot string) ([]string, error) {
var pkgs []string var pkgs []string
src := filepath.Join(goroot, "src") + string(filepath.Separator) src := filepath.Join(goroot, "src") + string(filepath.Separator)
walkFn := func(path string, fi fs.FileInfo, err error) error { walkFn := func(path string, d fs.DirEntry, err error) error {
if err != nil || !fi.IsDir() || path == src { if err != nil || !d.IsDir() || path == src {
return nil return nil
} }
@ -528,7 +528,7 @@ func listStdPkgs(goroot string) ([]string, error) {
pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/")) pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/"))
return nil return nil
} }
if err := filepath.Walk(src, walkFn); err != nil { if err := filepath.WalkDir(src, walkFn); err != nil {
return nil, err return nil, err
} }
return pkgs, nil return pkgs, nil

View File

@ -69,8 +69,8 @@ func main() {
flag.Parse() flag.Parse()
fset := token.NewFileSet() fset := token.NewFileSet()
nheadings := 0 nheadings := 0
err := filepath.Walk(*root, func(path string, fi fs.FileInfo, err error) error { err := filepath.WalkDir(*root, func(path string, info fs.DirEntry, err error) error {
if !fi.IsDir() { if !info.IsDir() {
return nil return nil
} }
pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments) pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments)

View File

@ -503,7 +503,7 @@ func makeText(name string) ([]byte, error) {
return nil, err return nil, err
} }
case "go": case "go":
err := filepath.Walk("../..", func(path string, info fs.FileInfo, err error) error { err := filepath.WalkDir("../..", func(path string, info fs.DirEntry, err error) error {
if err == nil && strings.HasSuffix(path, ".go") && !info.IsDir() { if err == nil && strings.HasSuffix(path, ".go") && !info.IsDir() {
file, err := ioutil.ReadFile(path) file, err := ioutil.ReadFile(path)
if err != nil { if err != nil {

View File

@ -14,6 +14,7 @@ import (
"fmt" "fmt"
"hash/fnv" "hash/fnv"
"io" "io"
"io/fs"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -1793,7 +1794,7 @@ func overlayDir(dstRoot, srcRoot string) error {
return err return err
} }
return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error { return filepath.WalkDir(srcRoot, func(srcPath string, d fs.DirEntry, err error) error {
if err != nil || srcPath == srcRoot { if err != nil || srcPath == srcRoot {
return err return err
} }
@ -1804,14 +1805,16 @@ func overlayDir(dstRoot, srcRoot string) error {
} }
dstPath := filepath.Join(dstRoot, suffix) dstPath := filepath.Join(dstRoot, suffix)
perm := info.Mode() & os.ModePerm var info fs.FileInfo
if info.Mode()&os.ModeSymlink != 0 { if d.Type()&os.ModeSymlink != 0 {
info, err = os.Stat(srcPath) info, err = os.Stat(srcPath)
if err != nil { } else {
return err info, err = d.Info()
}
perm = info.Mode() & os.ModePerm
} }
if err != nil {
return err
}
perm := info.Mode() & os.ModePerm
// Always copy directories (don't symlink them). // Always copy directories (don't symlink them).
// If we add a file in the overlay, we don't want to add it in the original. // If we add a file in the overlay, we don't want to add it in the original.

View File

@ -27,11 +27,11 @@ func main() {
// Walk the entire Go repository source tree (without GOROOT/pkg), // Walk the entire Go repository source tree (without GOROOT/pkg),
// skipping directories that start with "." and named "testdata", // skipping directories that start with "." and named "testdata",
// and ensure all .bat files found have exact CRLF line endings. // and ensure all .bat files found have exact CRLF line endings.
err := filepath.Walk(runtime.GOROOT(), func(path string, fi os.FileInfo, err error) error { err := filepath.WalkDir(runtime.GOROOT(), func(path string, d os.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
if fi.IsDir() && (strings.HasPrefix(fi.Name(), ".") || fi.Name() == "testdata") { if d.IsDir() && (strings.HasPrefix(d.Name(), ".") || d.Name() == "testdata") {
return filepath.SkipDir return filepath.SkipDir
} }
if path == filepath.Join(runtime.GOROOT(), "pkg") { if path == filepath.Join(runtime.GOROOT(), "pkg") {
@ -39,7 +39,7 @@ func main() {
// Skip it to avoid false positives. (Also see golang.org/issue/37929.) // Skip it to avoid false positives. (Also see golang.org/issue/37929.)
return filepath.SkipDir return filepath.SkipDir
} }
if filepath.Ext(fi.Name()) == ".bat" { if filepath.Ext(d.Name()) == ".bat" {
enforceBatchStrictCRLF(path) enforceBatchStrictCRLF(path)
} }
return nil return nil