// Copyright 2024 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package fsys import ( "io/fs" "path/filepath" ) // Copied from path/filepath. // WalkDir is like filepath.WalkDir but over the virtual file system. func WalkDir(root string, fn fs.WalkDirFunc) error { info, err := Lstat(root) if err != nil { err = fn(root, nil, err) } else { err = walkDir(root, fs.FileInfoToDirEntry(info), fn) } if err == filepath.SkipDir || err == filepath.SkipAll { return nil } return err } // walkDir recursively descends path, calling walkDirFn. func walkDir(path string, d fs.DirEntry, walkDirFn fs.WalkDirFunc) error { if err := walkDirFn(path, d, nil); err != nil || !d.IsDir() { if err == filepath.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 { if err == filepath.SkipDir && d.IsDir() { err = nil } return err } } for _, d1 := range dirs { path1 := filepath.Join(path, d1.Name()) if err := walkDir(path1, d1, walkDirFn); err != nil { if err == filepath.SkipDir { break } return err } } return nil }