watch: use WalkDir to speed up file listing (#4684)

`WalkDir` is new in Go 1.16 and avoids calling `os.Lstat` on
every visited file and directory. In most cases, we don't need
that info, so this will help reduce I/O when listing files,
which can be helpful for particularly big monorepos.
This commit is contained in:
Milas Bowman 2021-06-28 10:30:53 -04:00 committed by Nicolas De loof
parent 1f5bfe8882
commit 7161778ccf

View File

@ -4,6 +4,7 @@ package watch
import ( import (
"fmt" "fmt"
"io/fs"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -92,12 +93,12 @@ func (d *naiveNotify) watchRecursively(dir string) error {
return errors.Wrapf(err, "watcher.Add(%q)", dir) return errors.Wrapf(err, "watcher.Add(%q)", dir)
} }
return filepath.Walk(dir, func(path string, mode os.FileInfo, err error) error { return filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
if !mode.IsDir() { if !info.IsDir() {
return nil return nil
} }
@ -163,7 +164,7 @@ func (d *naiveNotify) loop() {
// because it's a bit more elegant that way. // because it's a bit more elegant that way.
// //
// TODO(dbentley): if there's a delete should we call d.watcher.Remove to prevent leaking? // TODO(dbentley): if there's a delete should we call d.watcher.Remove to prevent leaking?
err := filepath.Walk(e.Name, func(path string, mode os.FileInfo, err error) error { err := filepath.WalkDir(e.Name, func(path string, info fs.DirEntry, err error) error {
if err != nil { if err != nil {
return err return err
} }
@ -175,7 +176,7 @@ func (d *naiveNotify) loop() {
// TODO(dmiller): symlinks 😭 // TODO(dmiller): symlinks 😭
shouldWatch := false shouldWatch := false
if mode.IsDir() { if info.IsDir() {
// watch directories unless we can skip them entirely // watch directories unless we can skip them entirely
shouldSkipDir, err := d.shouldSkipDir(path) shouldSkipDir, err := d.shouldSkipDir(path)
if err != nil { if err != nil {