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  }