Skip to content

Commit c32140f

Browse files
committed
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>
1 parent 0433845 commit c32140f

File tree

17 files changed

+65
-45
lines changed

17 files changed

+65
-45
lines changed

src/cmd/compile/fmt_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import (
5252
"go/types"
5353
"internal/testenv"
5454
"io"
55+
"io/fs"
5556
"io/ioutil"
5657
"log"
5758
"os"
@@ -89,7 +90,7 @@ func TestFormats(t *testing.T) {
8990
testenv.MustHaveGoBuild(t) // more restrictive than necessary, but that's ok
9091

9192
// process all directories
92-
filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
93+
filepath.WalkDir(".", func(path string, info fs.DirEntry, err error) error {
9394
if info.IsDir() {
9495
if info.Name() == "testdata" {
9596
return filepath.SkipDir

src/cmd/dist/test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,7 @@ func (t *tester) makeGOROOTUnwritable() (undo func()) {
15091509
}
15101510
gocacheSubdir, _ := filepath.Rel(dir, gocache)
15111511

1512+
// Note: Can't use WalkDir here, because this has to compile with Go 1.4.
15121513
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
15131514
if suffix := strings.TrimPrefix(path, dir+string(filepath.Separator)); suffix != "" {
15141515
if suffix == gocacheSubdir {

src/cmd/fix/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,10 @@ func report(err error) {
234234
}
235235

236236
func walkDir(path string) {
237-
filepath.Walk(path, visitFile)
237+
filepath.WalkDir(path, visitFile)
238238
}
239239

240-
func visitFile(path string, f fs.FileInfo, err error) error {
240+
func visitFile(path string, f fs.DirEntry, err error) error {
241241
if err == nil && isGoFile(f) {
242242
err = processFile(path, false)
243243
}
@@ -247,7 +247,7 @@ func visitFile(path string, f fs.FileInfo, err error) error {
247247
return nil
248248
}
249249

250-
func isGoFile(f fs.FileInfo) bool {
250+
func isGoFile(f fs.DirEntry) bool {
251251
// ignore non-Go files
252252
name := f.Name()
253253
return !f.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".go")

src/cmd/go/go_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ func (tg *testgoData) cleanup() {
774774
func removeAll(dir string) error {
775775
// module cache has 0444 directories;
776776
// make them writable in order to remove content.
777-
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
777+
filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
778778
// chmod not only directories, but also things that we couldn't even stat
779779
// due to permission errors: they may also be unreadable directories.
780780
if err != nil || info.IsDir() {
@@ -820,8 +820,8 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
820820
} {
821821
srcdir := filepath.Join(testGOROOT, copydir)
822822
tg.tempDir(filepath.Join("goroot", copydir))
823-
err := filepath.Walk(srcdir,
824-
func(path string, info fs.FileInfo, err error) error {
823+
err := filepath.WalkDir(srcdir,
824+
func(path string, info fs.DirEntry, err error) error {
825825
if err != nil {
826826
return err
827827
}
@@ -838,9 +838,6 @@ func TestNewReleaseRebuildsStalePackagesInGOPATH(t *testing.T) {
838838
return err
839839
}
840840
tg.tempFile(dest, string(data))
841-
if err := os.Chmod(tg.path(dest), info.Mode()|0200); err != nil {
842-
return err
843-
}
844841
return nil
845842
})
846843
if err != nil {

src/cmd/go/internal/modfetch/fetch.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,10 @@ func makeDirsReadOnly(dir string) {
318318
mode fs.FileMode
319319
}
320320
var dirs []pathMode // in lexical order
321-
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
322-
if err == nil && info.Mode()&0222 != 0 {
323-
if info.IsDir() {
321+
filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
322+
if err == nil && d.IsDir() {
323+
info, err := d.Info()
324+
if err == nil && info.Mode()&0222 != 0 {
324325
dirs = append(dirs, pathMode{path, info.Mode()})
325326
}
326327
}
@@ -337,7 +338,7 @@ func makeDirsReadOnly(dir string) {
337338
// any permission changes needed to do so.
338339
func RemoveAll(dir string) error {
339340
// Module cache has 0555 directories; make them writable in order to remove content.
340-
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
341+
filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
341342
if err != nil {
342343
return nil // ignore errors walking in file system
343344
}

src/cmd/go/internal/version/version.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,15 @@ func runVersion(ctx context.Context, cmd *base.Command, args []string) {
8888

8989
// scanDir scans a directory for executables to run scanFile on.
9090
func scanDir(dir string) {
91-
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
92-
if info.Mode().IsRegular() || info.Mode()&fs.ModeSymlink != 0 {
91+
filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
92+
if d.Type().IsRegular() || d.Type()&fs.ModeSymlink != 0 {
93+
info, err := d.Info()
94+
if err != nil {
95+
if *versionV {
96+
fmt.Fprintf(os.Stderr, "%s: %v\n", path, err)
97+
}
98+
return nil
99+
}
93100
scanFile(path, info, *versionV)
94101
}
95102
return nil
@@ -120,6 +127,7 @@ func scanFile(file string, info fs.FileInfo, mustPrint bool) {
120127
}
121128
info = i
122129
}
130+
123131
if !isExe(file, info) {
124132
if mustPrint {
125133
fmt.Fprintf(os.Stderr, "%s: not executable file\n", file)

src/cmd/go/testdata/addmod.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ func main() {
122122
{Name: ".info", Data: info},
123123
}
124124
dir = filepath.Clean(dir)
125-
err = filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
126-
if !info.Mode().IsRegular() {
125+
err = filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
126+
if !info.Type().IsRegular() {
127127
return nil
128128
}
129129
name := info.Name()

src/cmd/go/testdata/savedir.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func main() {
4949

5050
a := new(txtar.Archive)
5151
dir = filepath.Clean(dir)
52-
filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
52+
filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
5353
if path == dir {
5454
return nil
5555
}
@@ -60,7 +60,7 @@ func main() {
6060
}
6161
return nil
6262
}
63-
if !info.Mode().IsRegular() {
63+
if !info.Type().IsRegular() {
6464
return nil
6565
}
6666
data, err := ioutil.ReadFile(path)

src/cmd/gofmt/gofmt.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func initParserMode() {
7474
}
7575
}
7676

77-
func isGoFile(f fs.FileInfo) bool {
77+
func isGoFile(f fs.DirEntry) bool {
7878
// ignore non-Go files
7979
name := f.Name()
8080
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
164164
return err
165165
}
166166

167-
func visitFile(path string, f fs.FileInfo, err error) error {
167+
func visitFile(path string, f fs.DirEntry, err error) error {
168168
if err == nil && isGoFile(f) {
169169
err = processFile(path, nil, os.Stdout, false)
170170
}
@@ -177,7 +177,7 @@ func visitFile(path string, f fs.FileInfo, err error) error {
177177
}
178178

179179
func walkDir(path string) {
180-
filepath.Walk(path, visitFile)
180+
filepath.WalkDir(path, visitFile)
181181
}
182182

183183
func main() {

src/cmd/gofmt/long_test.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ func testFiles(t *testing.T, filenames <-chan string, done chan<- int) {
108108
func genFilenames(t *testing.T, filenames chan<- string) {
109109
defer close(filenames)
110110

111-
handleFile := func(filename string, fi fs.FileInfo, err error) error {
111+
handleFile := func(filename string, d fs.DirEntry, err error) error {
112112
if err != nil {
113113
t.Error(err)
114114
return nil
115115
}
116-
if isGoFile(fi) {
116+
if isGoFile(d) {
117117
filenames <- filename
118118
nfiles++
119119
}
@@ -124,13 +124,13 @@ func genFilenames(t *testing.T, filenames chan<- string) {
124124
if *files != "" {
125125
for _, filename := range strings.Split(*files, ",") {
126126
fi, err := os.Stat(filename)
127-
handleFile(filename, fi, err)
127+
handleFile(filename, &statDirEntry{fi}, err)
128128
}
129129
return // ignore files under -root
130130
}
131131

132132
// otherwise, test all Go files under *root
133-
filepath.Walk(*root, handleFile)
133+
filepath.WalkDir(*root, handleFile)
134134
}
135135

136136
func TestAll(t *testing.T) {
@@ -164,3 +164,12 @@ func TestAll(t *testing.T) {
164164
fmt.Printf("processed %d files\n", nfiles)
165165
}
166166
}
167+
168+
type statDirEntry struct {
169+
info fs.FileInfo
170+
}
171+
172+
func (d *statDirEntry) Name() string { return d.info.Name() }
173+
func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
174+
func (d *statDirEntry) Type() fs.FileMode { return d.info.Mode().Type() }
175+
func (d *statDirEntry) Info() (fs.FileInfo, error) { return d.info, nil }

src/cmd/internal/moddeps/moddeps_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func findGorootModules(t *testing.T) []gorootModule {
3333
goBin := testenv.GoToolPath(t)
3434

3535
goroot.once.Do(func() {
36-
goroot.err = filepath.Walk(runtime.GOROOT(), func(path string, info fs.FileInfo, err error) error {
36+
goroot.err = filepath.WalkDir(runtime.GOROOT(), func(path string, info fs.DirEntry, err error) error {
3737
if err != nil {
3838
return err
3939
}

src/compress/gzip/issue14937_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TestGZIPFilesHaveZeroMTimes(t *testing.T) {
3131
t.Fatal("error evaluating GOROOT: ", err)
3232
}
3333
var files []string
34-
err = filepath.Walk(goroot, func(path string, info fs.FileInfo, err error) error {
34+
err = filepath.WalkDir(goroot, func(path string, info fs.DirEntry, err error) error {
3535
if err != nil {
3636
return err
3737
}

src/go/build/deps_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,8 @@ func listStdPkgs(goroot string) ([]string, error) {
510510
var pkgs []string
511511

512512
src := filepath.Join(goroot, "src") + string(filepath.Separator)
513-
walkFn := func(path string, fi fs.FileInfo, err error) error {
514-
if err != nil || !fi.IsDir() || path == src {
513+
walkFn := func(path string, d fs.DirEntry, err error) error {
514+
if err != nil || !d.IsDir() || path == src {
515515
return nil
516516
}
517517

@@ -528,7 +528,7 @@ func listStdPkgs(goroot string) ([]string, error) {
528528
pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/"))
529529
return nil
530530
}
531-
if err := filepath.Walk(src, walkFn); err != nil {
531+
if err := filepath.WalkDir(src, walkFn); err != nil {
532532
return nil, err
533533
}
534534
return pkgs, nil

src/go/doc/headscan.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ func main() {
6969
flag.Parse()
7070
fset := token.NewFileSet()
7171
nheadings := 0
72-
err := filepath.Walk(*root, func(path string, fi fs.FileInfo, err error) error {
73-
if !fi.IsDir() {
72+
err := filepath.WalkDir(*root, func(path string, info fs.DirEntry, err error) error {
73+
if !info.IsDir() {
7474
return nil
7575
}
7676
pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments)

src/index/suffixarray/suffixarray_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ func makeText(name string) ([]byte, error) {
503503
return nil, err
504504
}
505505
case "go":
506-
err := filepath.Walk("../..", func(path string, info fs.FileInfo, err error) error {
506+
err := filepath.WalkDir("../..", func(path string, info fs.DirEntry, err error) error {
507507
if err == nil && strings.HasSuffix(path, ".go") && !info.IsDir() {
508508
file, err := ioutil.ReadFile(path)
509509
if err != nil {

test/run.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"fmt"
1515
"hash/fnv"
1616
"io"
17+
"io/fs"
1718
"io/ioutil"
1819
"log"
1920
"os"
@@ -1793,7 +1794,7 @@ func overlayDir(dstRoot, srcRoot string) error {
17931794
return err
17941795
}
17951796

1796-
return filepath.Walk(srcRoot, func(srcPath string, info os.FileInfo, err error) error {
1797+
return filepath.WalkDir(srcRoot, func(srcPath string, d fs.DirEntry, err error) error {
17971798
if err != nil || srcPath == srcRoot {
17981799
return err
17991800
}
@@ -1804,14 +1805,16 @@ func overlayDir(dstRoot, srcRoot string) error {
18041805
}
18051806
dstPath := filepath.Join(dstRoot, suffix)
18061807

1807-
perm := info.Mode() & os.ModePerm
1808-
if info.Mode()&os.ModeSymlink != 0 {
1808+
var info fs.FileInfo
1809+
if d.Type()&os.ModeSymlink != 0 {
18091810
info, err = os.Stat(srcPath)
1810-
if err != nil {
1811-
return err
1812-
}
1813-
perm = info.Mode() & os.ModePerm
1811+
} else {
1812+
info, err = d.Info()
18141813
}
1814+
if err != nil {
1815+
return err
1816+
}
1817+
perm := info.Mode() & os.ModePerm
18151818

18161819
// Always copy directories (don't symlink them).
18171820
// If we add a file in the overlay, we don't want to add it in the original.

test/winbatch.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ func main() {
2727
// Walk the entire Go repository source tree (without GOROOT/pkg),
2828
// skipping directories that start with "." and named "testdata",
2929
// and ensure all .bat files found have exact CRLF line endings.
30-
err := filepath.Walk(runtime.GOROOT(), func(path string, fi os.FileInfo, err error) error {
30+
err := filepath.WalkDir(runtime.GOROOT(), func(path string, d os.DirEntry, err error) error {
3131
if err != nil {
3232
return err
3333
}
34-
if fi.IsDir() && (strings.HasPrefix(fi.Name(), ".") || fi.Name() == "testdata") {
34+
if d.IsDir() && (strings.HasPrefix(d.Name(), ".") || d.Name() == "testdata") {
3535
return filepath.SkipDir
3636
}
3737
if path == filepath.Join(runtime.GOROOT(), "pkg") {
3838
// GOROOT/pkg is known to contain generated artifacts, not source code.
3939
// Skip it to avoid false positives. (Also see golang.org/issue/37929.)
4040
return filepath.SkipDir
4141
}
42-
if filepath.Ext(fi.Name()) == ".bat" {
42+
if filepath.Ext(d.Name()) == ".bat" {
4343
enforceBatchStrictCRLF(path)
4444
}
4545
return nil

0 commit comments

Comments
 (0)