mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
refactor: implement package-manager-specific extractors & replace osv-scanner with scalibr
This commit is contained in:
+17
-99
@@ -4,23 +4,19 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
||||
"github.com/google/osv-scanner/pkg/lockfile"
|
||||
"github.com/safedep/dry/log"
|
||||
)
|
||||
|
||||
type ExtractorConfig struct {
|
||||
// List of extractors used by an ecosystem
|
||||
ExtractorsName []string
|
||||
ExtractorEcosystem packagev1.Ecosystem
|
||||
ScanDir string
|
||||
ExtractorPackageManager PackageManagerName
|
||||
ScanDir string
|
||||
}
|
||||
|
||||
type extractor struct {
|
||||
Config ExtractorConfig
|
||||
extractorManager *ExtractorManager
|
||||
extractorManager ExtractorManager
|
||||
}
|
||||
|
||||
func NewDefaultExtractorConfig() *ExtractorConfig {
|
||||
@@ -32,7 +28,7 @@ func NewDefaultExtractorConfig() *ExtractorConfig {
|
||||
func New(config ExtractorConfig) *extractor {
|
||||
return &extractor{
|
||||
Config: config,
|
||||
extractorManager: NewExtractorManager(),
|
||||
extractorManager: *NewExtractorManager(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +46,14 @@ func (e *extractor) ExtractManifest() ([]*packagev1.PackageVersion, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
extractor, err := e.getExtractorForFile()
|
||||
if err != nil {
|
||||
log.Warnf("failed to get extractor\n")
|
||||
continue
|
||||
}
|
||||
|
||||
// Extract packages from this lockfile
|
||||
packages, err := e.extractFromLockfile(filePath)
|
||||
packages, err := extractor.Extract(filePath, e.Config.ScanDir)
|
||||
if err != nil {
|
||||
log.Warnf("failed to extract from %s: %v\n", filePath, err)
|
||||
continue
|
||||
@@ -64,97 +66,13 @@ func (e *extractor) ExtractManifest() ([]*packagev1.PackageVersion, error) {
|
||||
}
|
||||
|
||||
func (e *extractor) getFilesToCheck() []string {
|
||||
// If specific extractors are configured, use those
|
||||
if len(e.Config.ExtractorsName) > 0 {
|
||||
return e.Config.ExtractorsName
|
||||
}
|
||||
|
||||
// If ecosystem is specified, return files for that ecosystem
|
||||
if e.Config.ExtractorEcosystem != packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED {
|
||||
return e.extractorManager.GetSupportedFilesForEcosystem(e.Config.ExtractorEcosystem)
|
||||
}
|
||||
|
||||
// If no ecosystem specified, check all known extractors
|
||||
return e.extractorManager.GetAllSupportedFiles()
|
||||
return e.extractorManager.GetSupportedFilesForPackageManager(e.Config.ExtractorPackageManager)
|
||||
}
|
||||
|
||||
func (e *extractor) extractFromLockfile(path string) ([]*packagev1.PackageVersion, error) {
|
||||
filename := filepath.Base(path)
|
||||
|
||||
// Find the appropriate extractor for this file
|
||||
ecosystemExtractor, ecosystem, err := e.getExtractorForFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (e *extractor) getExtractorForFile() (PackageManagerExtractor, error) {
|
||||
extractor := e.extractorManager.GetExtractorForPackageManager(e.Config.ExtractorPackageManager)
|
||||
if extractor == nil {
|
||||
return nil, fmt.Errorf("no extractor found for package manager: %s", e.Config.ExtractorPackageManager)
|
||||
}
|
||||
|
||||
// Open the file as a DepFile for extraction
|
||||
depFile, err := lockfile.OpenLocalDepFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file %s: %w", path, err)
|
||||
}
|
||||
defer depFile.Close()
|
||||
|
||||
// Extract dependencies using the appropriate extractor
|
||||
deps, err := ecosystemExtractor.Extract(depFile, filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to extract from %s: %w", path, err)
|
||||
}
|
||||
|
||||
packages := e.convertToPackageVersions(deps, ecosystem)
|
||||
return packages, nil
|
||||
}
|
||||
|
||||
func (e *extractor) getExtractorForFile(filename string) (EcosystemExtractor, packagev1.Ecosystem, error) {
|
||||
// If ecosystem is configured, use that directly
|
||||
if e.Config.ExtractorEcosystem != packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED {
|
||||
extractor, exists := e.extractorManager.GetExtractorForEcosystem(e.Config.ExtractorEcosystem)
|
||||
if !exists {
|
||||
return nil, packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED, fmt.Errorf("no extractor found for ecosystem: %v", e.Config.ExtractorEcosystem)
|
||||
}
|
||||
|
||||
// Verify the file is supported by this ecosystem
|
||||
supportedFiles := extractor.GetSupportedFiles()
|
||||
for _, supportedFile := range supportedFiles {
|
||||
if filename == supportedFile || strings.Contains(filename, supportedFile) {
|
||||
return extractor, e.Config.ExtractorEcosystem, nil
|
||||
}
|
||||
}
|
||||
return nil, packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED, fmt.Errorf("file %s not supported by ecosystem %v", filename, e.Config.ExtractorEcosystem)
|
||||
}
|
||||
|
||||
// Try to find extractor by filename
|
||||
for ecosystem, extractor := range e.extractorManager.extractors {
|
||||
supportedFiles := extractor.GetSupportedFiles()
|
||||
for _, supportedFile := range supportedFiles {
|
||||
if filename == supportedFile || strings.Contains(filename, supportedFile) {
|
||||
return extractor, ecosystem, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED, fmt.Errorf("unsupported lockfile type: %s", filename)
|
||||
}
|
||||
|
||||
func (e *extractor) convertToPackageVersions(deps []lockfile.PackageDetails, ecosystem packagev1.Ecosystem) []*packagev1.PackageVersion {
|
||||
var packages []*packagev1.PackageVersion
|
||||
|
||||
for _, dep := range deps {
|
||||
// Use the configured ecosystem if provided, otherwise use the detected one
|
||||
targetEcosystem := ecosystem
|
||||
if e.Config.ExtractorEcosystem != packagev1.Ecosystem_ECOSYSTEM_UNSPECIFIED {
|
||||
targetEcosystem = e.Config.ExtractorEcosystem
|
||||
}
|
||||
|
||||
packageVer := &packagev1.PackageVersion{
|
||||
Package: &packagev1.Package{
|
||||
Name: dep.Name,
|
||||
Ecosystem: targetEcosystem,
|
||||
},
|
||||
Version: dep.Version,
|
||||
}
|
||||
|
||||
packages = append(packages, packageVer)
|
||||
}
|
||||
|
||||
return packages
|
||||
return extractor, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user