github.com/anchore/syft@v1.38.2/syft/internal/fileresolver/directory.go (about)

     1  package fileresolver
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/anchore/stereoscope/pkg/filetree"
     8  	"github.com/anchore/syft/syft/file"
     9  )
    10  
    11  var ErrSkipPath = errors.New("skip path")
    12  
    13  var _ file.Resolver = (*Directory)(nil)
    14  
    15  // Directory implements path and content access for the directory data source.
    16  type Directory struct {
    17  	FiletreeResolver
    18  	path    string
    19  	indexer *directoryIndexer
    20  }
    21  
    22  func NewFromDirectory(root, base string, pathFilters ...PathIndexVisitor) (*Directory, error) {
    23  	resolver, err := newFromDirectoryWithoutIndex(root, base, pathFilters...)
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  
    28  	return resolver, resolver.buildIndex()
    29  }
    30  
    31  func newFromDirectoryWithoutIndex(root, base string, pathFilters ...PathIndexVisitor) (*Directory, error) {
    32  	chroot, err := NewChrootContextFromCWD(root, base)
    33  	if err != nil {
    34  		return nil, fmt.Errorf("unable to interpret chroot context: %w", err)
    35  	}
    36  
    37  	cleanRoot := chroot.Root()
    38  	cleanBase := chroot.Base()
    39  
    40  	return &Directory{
    41  		path: cleanRoot,
    42  		FiletreeResolver: FiletreeResolver{
    43  			Chroot: *chroot,
    44  			Tree:   filetree.New(),
    45  			Index:  filetree.NewIndex(),
    46  			Opener: nativeOSFileOpener,
    47  		},
    48  		indexer: newDirectoryIndexer(cleanRoot, cleanBase, pathFilters...),
    49  	}, nil
    50  }
    51  
    52  func (r *Directory) buildIndex() error {
    53  	if r.indexer == nil {
    54  		return fmt.Errorf("no directory indexer configured")
    55  	}
    56  	tree, index, err := r.indexer.build()
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	r.Tree = tree
    62  	r.Index = index
    63  	r.SearchContext = filetree.NewSearchContext(tree, index)
    64  
    65  	return nil
    66  }
    67  
    68  // Stringer to represent a directory path data source
    69  func (r *Directory) String() string {
    70  	return fmt.Sprintf("dir:%s", r.path)
    71  }