diff options
| author | Dmitri Shuralyov <dmitshur@golang.org> | 2020-11-05 01:05:04 +0000 |
|---|---|---|
| committer | Dmitri Shuralyov <dmitshur@golang.org> | 2020-11-05 14:54:35 +0000 |
| commit | 74ec40fc8acffb81f17ccbaa498b15f694c25e4d (patch) | |
| tree | ef48d33bd8313c6c10ffe1c1df1ed4ddec48ec8a /src/path/filepath/path.go | |
| parent | 05568315f2ae8fb86112e63966b46c2dcc8ab6e2 (diff) | |
| download | go-74ec40fc8acffb81f17ccbaa498b15f694c25e4d.tar.xz | |
path/filepath: revert "add WalkDir"
This reverts CL 266240.
Reason for revert: tests aren't passing on windows-amd64-longtest.
Change-Id: If323c6254a42aff0418e2c0a9531f3d4c829a242
Reviewed-on: https://go-review.googlesource.com/c/go/+/267798
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
Diffstat (limited to 'src/path/filepath/path.go')
| -rw-r--r-- | src/path/filepath/path.go | 211 |
1 files changed, 23 insertions, 188 deletions
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go index 3f7e5c713d..dffd27db14 100644 --- a/src/path/filepath/path.go +++ b/src/path/filepath/path.go @@ -336,130 +336,25 @@ func Rel(basepath, targpath string) (string, error) { // as an error by any function. var SkipDir = errors.New("skip this directory") -// WalkDirFunc is the type of the function called by WalkDir to visit -// each each file or directory. +// WalkFunc is the type of the function called for each file or directory +// visited by Walk. The path argument contains the argument to Walk as a +// prefix; that is, if Walk is called with "dir", which is a directory +// containing the file "a", the walk function will be called with argument +// "dir/a". The info argument is the fs.FileInfo for the named path. // -// The path argument contains the argument to Walk as a prefix. -// That is, if Walk is called with root argument "dir" and finds a file -// named "a" in that directory, the walk function will be called with -// argument "dir/a". -// -// The directory and file are joined with Join, which may clean the -// directory name: if Walk is called with the root argument "x/../dir" -// and finds a file named "a" in that directory, the walk function will -// be called with argument "dir/a", not "x/../dir/a". -// -// The d argument is the fs.DirEntry for the named path. -// -// The error result returned by the function controls how WalkDir -// continues. If the function returns the special value SkipDir, WalkDir -// skips the current directory (path if d.IsDir() is true, otherwise -// path's parent directory). Otherwise, if the function returns a non-nil -// error, WalkDir stops entirely and returns that error. -// -// The err argument reports an error related to path, signaling that -// WalkDir will not walk into that directory. The function can decide how -// to handle that error; as described earlier, returning the error will -// cause WalkDir to stop walking the entire tree. -// -// WalkDir calls the function with a non-nil err argument in two cases. -// -// First, if the initial os.Lstat on the root directory fails, WalkDir -// calls the function with path set to root, d set to nil, and err set to -// the error from os.Lstat. -// -// Second, if a directory's ReadDir method fails, WalkDir calls the -// function with path set to the directory's path, d set to an -// fs.DirEntry describing the directory, and err set to the error from -// ReadDir. In this second case, the function is called twice with the -// path of the directory: the first call is before the directory read is -// attempted and has err set to nil, giving the function a chance to -// return SkipDir and avoid the ReadDir entirely. The second call is -// after a failed ReadDir and reports the error from ReadDir. -// (If ReadDir succeeds, there is no second call.) -// -// The differences between WalkDirFunc compared to WalkFunc are: -// -// - The second argument has type fs.DirEntry instead of fs.FileInfo. -// - The function is called before reading a directory, to allow SkipDir -// to bypass the directory read entirely. -// - If a directory read fails, the function is called a second time -// for that directory to report the error. -// -type WalkDirFunc func(path string, d fs.DirEntry, err error) error - -// WalkFunc is the type of the function called by Walk to visit each each -// file or directory. -// -// The path argument contains the argument to Walk as a prefix. -// That is, if Walk is called with root argument "dir" and finds a file -// named "a" in that directory, the walk function will be called with -// argument "dir/a". -// -// The directory and file are joined with Join, which may clean the -// directory name: if Walk is called with the root argument "x/../dir" -// and finds a file named "a" in that directory, the walk function will -// be called with argument "dir/a", not "x/../dir/a". -// -// The info argument is the fs.FileInfo for the named path. -// -// The error result returned by the function controls how Walk continues. -// If the function returns the special value SkipDir, Walk skips the -// current directory (path if info.IsDir() is true, otherwise path's -// parent directory). Otherwise, if the function returns a non-nil error, -// Walk stops entirely and returns that error. -// -// The err argument reports an error related to path, signaling that Walk -// will not walk into that directory. The function can decide how to -// handle that error; as described earlier, returning the error will -// cause Walk to stop walking the entire tree. -// -// Walk calls the function with a non-nil err argument in two cases. -// -// First, if an os.Lstat on the root directory or any directory or file -// in the tree fails, Walk calls the function with path set to that -// directory or file's path, info set to nil, and err set to the error -// from os.Lstat. -// -// Second, if a directory's Readdirnames method fails, Walk calls the -// function with path set to the directory's path, info, set to an -// fs.FileInfo describing the directory, and err set to the error from -// Readdirnames. +// If there was a problem walking to the file or directory named by path, the +// incoming error will describe the problem and the function can decide how +// to handle that error (and Walk will not descend into that directory). In the +// case of an error, the info argument will be nil. If an error is returned, +// processing stops. The sole exception is when the function returns the special +// value SkipDir. If the function returns SkipDir when invoked on a directory, +// Walk skips the directory's contents entirely. If the function returns SkipDir +// when invoked on a non-directory file, Walk skips the remaining files in the +// containing directory. type WalkFunc func(path string, info fs.FileInfo, err error) error var lstat = os.Lstat // for testing -// walkDir recursively descends path, calling walkDirFn. -func walkDir(path string, d fs.DirEntry, walkDirFn WalkDirFunc) error { - if err := walkDirFn(path, d, nil); err != nil || !d.IsDir() { - if err == SkipDir && d.IsDir() { - // Successfully skipped directory. - err = nil - } - return err - } - - dirs, err := readDir(path) - if err != nil { - // Second call, to report ReadDir error. - err = walkDirFn(path, d, err) - if err != nil { - return err - } - } - - for _, d1 := range dirs { - path1 := Join(path, d1.Name()) - if err := walkDir(path1, d1, walkDirFn); err != nil { - if err == SkipDir { - break - } - return err - } - } - return nil -} - // walk recursively descends path, calling walkFn. func walk(path string, info fs.FileInfo, walkFn WalkFunc) error { if !info.IsDir() { @@ -498,62 +393,18 @@ func walk(path string, info fs.FileInfo, walkFn WalkFunc) error { return nil } -// WalkDir walks the file tree rooted at root, calling fn for each file or -// directory in the tree, including root. -// -// All errors that arise visiting files and directories are filtered by fn: -// see the WalkDirFunc documentation for details. -// -// The files are walked in lexical order, which makes the output deterministic -// but requires WalkDir to read an entire directory into memory before proceeding -// to walk that directory. -// -// WalkDir does not follow symbolic links. -func WalkDir(root string, fn WalkDirFunc) error { - info, err := os.Lstat(root) - if err != nil { - err = fn(root, nil, err) - } else { - err = walkDir(root, &dirEntryFromInfo{info}, fn) - } - if err == SkipDir { - return nil - } - return err -} - -type dirEntryFromInfo struct { - fs.FileInfo -} - -func (e *dirEntryFromInfo) Type() fs.FileMode { - return e.Mode().Type() -} - -func (e *dirEntryFromInfo) Info() (fs.FileInfo, error) { - return e.FileInfo, nil -} - -// Walk walks the file tree rooted at root, calling fn for each file or -// directory in the tree, including root. -// -// All errors that arise visiting files and directories are filtered by fn: -// see the WalkFunc documentation for details. -// -// The files are walked in lexical order, which makes the output deterministic -// but requires Walk to read an entire directory into memory before proceeding -// to walk that directory. -// +// Walk walks the file tree rooted at root, calling walkFn for each file or +// directory in the tree, including root. All errors that arise visiting files +// and directories are filtered by walkFn. The files are walked in lexical +// order, which makes the output deterministic but means that for very +// large directories Walk can be inefficient. // Walk does not follow symbolic links. -// -// Walk is less efficient than WalkDir, introduced in Go 1.16, -// which avoids calling os.Lstat on every visited file or directory. -func Walk(root string, fn WalkFunc) error { +func Walk(root string, walkFn WalkFunc) error { info, err := os.Lstat(root) if err != nil { - err = fn(root, nil, err) + err = walkFn(root, nil, err) } else { - err = walk(root, info, fn) + err = walk(root, info, walkFn) } if err == SkipDir { return nil @@ -561,24 +412,8 @@ func Walk(root string, fn WalkFunc) error { return err } -// readDir reads the directory named by dirname and returns -// a sorted list of directory entries. -func readDir(dirname string) ([]fs.DirEntry, error) { - f, err := os.Open(dirname) - if err != nil { - return nil, err - } - dirs, err := f.ReadDir(-1) - f.Close() - if err != nil { - return nil, err - } - sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() }) - return dirs, nil -} - // readDirNames reads the directory named by dirname and returns -// a sorted list of directory entry names. +// a sorted list of directory entries. func readDirNames(dirname string) ([]string, error) { f, err := os.Open(dirname) if err != nil { |
