Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/fs/walk.go
1560 views
1
package fs
2
3
import (
4
"context"
5
"path"
6
"path/filepath"
7
8
"github.com/alist-org/alist/v3/internal/model"
9
"github.com/alist-org/alist/v3/internal/op"
10
)
11
12
// WalkFS traverses filesystem fs starting at name up to depth levels.
13
//
14
// WalkFS will stop when current depth > `depth`. For each visited node,
15
// WalkFS calls walkFn. If a visited file system node is a directory and
16
// walkFn returns path.SkipDir, walkFS will skip traversal of this node.
17
func WalkFS(ctx context.Context, depth int, name string, info model.Obj, walkFn func(reqPath string, info model.Obj) error) error {
18
// This implementation is based on Walk's code in the standard path/path package.
19
walkFnErr := walkFn(name, info)
20
if walkFnErr != nil {
21
if info.IsDir() && walkFnErr == filepath.SkipDir {
22
return nil
23
}
24
return walkFnErr
25
}
26
if !info.IsDir() || depth == 0 {
27
return nil
28
}
29
meta, _ := op.GetNearestMeta(name)
30
// Read directory names.
31
objs, err := List(context.WithValue(ctx, "meta", meta), name, &ListArgs{})
32
if err != nil {
33
return walkFnErr
34
}
35
for _, fileInfo := range objs {
36
filename := path.Join(name, fileInfo.GetName())
37
if err := WalkFS(ctx, depth-1, filename, fileInfo, walkFn); err != nil {
38
if err == filepath.SkipDir {
39
break
40
}
41
return err
42
}
43
}
44
return nil
45
}
46
47