mirror of
https://github.com/anchore/syft.git
synced 2026-11-04 00:16:38 +01:00
generalize common analyzer elements
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/imgbom/internal/log"
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
)
|
||||
|
||||
type GenericAnalyzer struct {
|
||||
globParserDispatch map[string]ParserFn
|
||||
pathParserDispatch map[string]ParserFn
|
||||
selectedFiles []file.Reference
|
||||
parsers map[file.Reference]ParserFn
|
||||
}
|
||||
|
||||
func NewGenericAnalyzer(pathParserDispatch map[string]ParserFn, globParserDispatch map[string]ParserFn) GenericAnalyzer {
|
||||
return GenericAnalyzer{
|
||||
globParserDispatch: globParserDispatch,
|
||||
pathParserDispatch: pathParserDispatch,
|
||||
selectedFiles: make([]file.Reference, 0),
|
||||
parsers: make(map[file.Reference]ParserFn),
|
||||
}
|
||||
}
|
||||
|
||||
func (a *GenericAnalyzer) register(files []file.Reference, parser ParserFn) {
|
||||
a.selectedFiles = append(a.selectedFiles, files...)
|
||||
for _, f := range files {
|
||||
a.parsers[f] = parser
|
||||
}
|
||||
}
|
||||
|
||||
func (a *GenericAnalyzer) clear() {
|
||||
a.selectedFiles = make([]file.Reference, 0)
|
||||
a.parsers = make(map[file.Reference]ParserFn)
|
||||
}
|
||||
|
||||
func (a *GenericAnalyzer) SelectFiles(trees []tree.FileTreeReader) []file.Reference {
|
||||
for _, tree := range trees {
|
||||
// select by exact path
|
||||
for path, parser := range a.globParserDispatch {
|
||||
f := tree.File(file.Path(path))
|
||||
if f != nil {
|
||||
a.register([]file.Reference{*f}, parser)
|
||||
}
|
||||
}
|
||||
|
||||
// select by pattern
|
||||
for globPattern, parser := range a.globParserDispatch {
|
||||
fileMatches, err := tree.FilesByGlob(globPattern)
|
||||
if err != nil {
|
||||
log.Errorf("failed to find files by glob: %s", globPattern)
|
||||
}
|
||||
if fileMatches != nil {
|
||||
a.register(fileMatches, parser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return a.selectedFiles
|
||||
}
|
||||
|
||||
func (a *GenericAnalyzer) Analyze(contents map[file.Reference]string, upstreamMatcher string) ([]pkg.Package, error) {
|
||||
defer a.clear()
|
||||
|
||||
packages := make([]pkg.Package, 0)
|
||||
|
||||
for reference, parser := range a.parsers {
|
||||
content, ok := contents[reference]
|
||||
if !ok {
|
||||
log.Errorf("analyzer '%s' missing file content: %+v", upstreamMatcher, reference)
|
||||
continue
|
||||
}
|
||||
|
||||
entries, err := parser(strings.NewReader(content))
|
||||
if err != nil {
|
||||
log.Errorf("analyzer '%s' failed to parse entries (reference=%+v): %w", upstreamMatcher, reference, err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
entry.FoundBy = upstreamMatcher
|
||||
entry.Source = []file.Reference{reference}
|
||||
|
||||
packages = append(packages, entry)
|
||||
}
|
||||
}
|
||||
|
||||
return packages, nil
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
)
|
||||
|
||||
type ParserFn func(io.Reader) ([]pkg.Package, error)
|
||||
Reference in New Issue
Block a user