github.com/anchore/syft@v1.38.2/internal/file/squashfs.go (about) 1 package file 2 3 import ( 4 "errors" 5 "io/fs" 6 "os" 7 "path/filepath" 8 9 "github.com/diskfs/go-diskfs/filesystem" 10 ) 11 12 type WalkDiskDirFunc func(fsys filesystem.FileSystem, path string, d os.FileInfo, err error) error 13 14 // WalkDiskDir walks the file tree within the go-diskfs filesystem at root, calling fn for each file or directory in the tree, including root. 15 // This is meant to mimic the behavior of fs.WalkDir in the standard library. 16 func WalkDiskDir(fsys filesystem.FileSystem, root string, fn WalkDiskDirFunc) error { 17 infos, err := fsys.ReadDir(root) 18 19 if err != nil { 20 return err 21 } 22 23 if len(infos) == 0 { 24 return nil 25 } 26 27 for _, info := range infos { 28 p := filepath.Join(root, info.Name()) 29 err = walkDiskDir(fsys, p, info, fn) 30 if err != nil { 31 if errors.Is(err, fs.SkipDir) { 32 continue 33 } 34 if errors.Is(err, fs.SkipAll) { 35 return nil 36 } 37 return err 38 } 39 } 40 41 return err 42 } 43 44 func walkDiskDir(fsys filesystem.FileSystem, name string, d os.FileInfo, walkDirFn WalkDiskDirFunc) error { 45 if err := walkDirFn(fsys, name, d, nil); err != nil { 46 if errors.Is(err, fs.SkipDir) && (d == nil || d.IsDir()) { 47 return nil 48 } 49 return err 50 } 51 52 isDir := d != nil && d.IsDir() 53 if d == nil { 54 _, err := fsys.ReadDir(name) 55 if err != nil { 56 return nil 57 } 58 isDir = true 59 } 60 61 if !isDir { 62 return nil 63 } 64 65 dirs, err := fsys.ReadDir(name) 66 if err != nil { 67 err = walkDirFn(fsys, name, d, err) 68 if err != nil { 69 if errors.Is(err, fs.SkipDir) { 70 return nil 71 } 72 return err 73 } 74 } 75 76 for _, d1 := range dirs { 77 name1 := filepath.Join(name, d1.Name()) 78 if err := walkDiskDir(fsys, name1, d1, walkDirFn); err != nil { 79 if errors.Is(err, fs.SkipDir) { 80 break 81 } 82 if errors.Is(err, fs.SkipAll) { 83 return err 84 } 85 return err 86 } 87 } 88 return nil 89 }