github.com/anchore/syft@v1.38.2/syft/internal/fileresolver/file.go (about) 1 package fileresolver 2 3 import ( 4 "fmt" 5 6 "github.com/anchore/stereoscope/pkg/filetree" 7 "github.com/anchore/syft/syft/file" 8 ) 9 10 // Compile time assurance that we meet the Resolver interface. 11 var _ file.Resolver = (*File)(nil) 12 13 // File implements path and content access for the file data source. 14 type File struct { 15 FiletreeResolver 16 path string 17 indexer *fileIndexer 18 } 19 20 // NewFromFile single file analyser 21 // path is the filepath of the file we're creating content access for 22 func NewFromFile(path string, pathFilters ...PathIndexVisitor) (*File, error) { 23 resolver, err := newFromFileWithoutIndex(path, pathFilters...) 24 if err != nil { 25 return nil, err 26 } 27 28 return resolver, resolver.buildIndex() 29 } 30 31 func newFromFileWithoutIndex(path string, pathFilters ...PathIndexVisitor) (*File, error) { 32 absParentDir, err := absoluteSymlinkFreePathToParent(path) 33 if err != nil { 34 return nil, err 35 } 36 37 chroot, err := NewChrootContextFromCWD(absParentDir, absParentDir) 38 if err != nil { 39 return nil, fmt.Errorf("unable to interpret chroot context: %w", err) 40 } 41 42 cleanBase := chroot.Base() 43 44 return &File{ 45 path: path, 46 FiletreeResolver: FiletreeResolver{ 47 Chroot: *chroot, 48 Tree: filetree.New(), 49 Index: filetree.NewIndex(), 50 Opener: nativeOSFileOpener, 51 }, 52 indexer: newFileIndexer(path, cleanBase, pathFilters...), 53 }, nil 54 } 55 56 func (r *File) buildIndex() error { 57 if r.indexer == nil { 58 return fmt.Errorf("no file indexer configured") 59 } 60 tree, index, err := r.indexer.build() 61 if err != nil { 62 return err 63 } 64 65 r.Tree = tree 66 r.Index = index 67 r.SearchContext = filetree.NewSearchContext(tree, index) 68 69 return nil 70 } 71 72 // Stringer to represent a file path data source 73 func (r *File) String() string { 74 return fmt.Sprintf("file:%s", r.path) 75 }