Files
pmg/extractor/ecosystems.go
T

102 lines
2.9 KiB
Go

package extractor
import (
"fmt"
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
"github.com/google/osv-scanner/pkg/lockfile"
)
// EcosystemExtractor defines the interface for ecosystem-specific extractors
type EcosystemExtractor interface {
GetSupportedFiles() []string
GetEcosystem() packagev1.Ecosystem
Extract(depFile lockfile.DepFile, filename string) ([]lockfile.PackageDetails, error)
}
// NpmExtractor handles NPM ecosystem lockfiles
type NpmExtractor struct{}
var NpmExtractors []string = []string{"package-lock.json", "pnpm-lock.yaml"}
func (n *NpmExtractor) GetSupportedFiles() []string {
return NpmExtractors
}
func (n *NpmExtractor) GetEcosystem() packagev1.Ecosystem {
return packagev1.Ecosystem_ECOSYSTEM_NPM
}
func (n *NpmExtractor) Extract(depFile lockfile.DepFile, filename string) ([]lockfile.PackageDetails, error) {
switch filename {
case "package-lock.json":
extractor := lockfile.NpmLockExtractor{}
return extractor.Extract(depFile)
case "pnpm-lock.yaml":
extractor := lockfile.PnpmLockExtractor{}
return extractor.Extract(depFile)
default:
return nil, fmt.Errorf("unsupported NPM lockfile: %s", filename)
}
}
// PyPiExtractor handles PyPI ecosystem lockfiles
type PyPiExtractor struct{}
var PyPiExtractors []string = []string{"requirements.txt", "Pipfile.lock"}
func (p *PyPiExtractor) GetSupportedFiles() []string {
return PyPiExtractors
}
func (p *PyPiExtractor) GetEcosystem() packagev1.Ecosystem {
return packagev1.Ecosystem_ECOSYSTEM_PYPI
}
func (p *PyPiExtractor) Extract(depFile lockfile.DepFile, filename string) ([]lockfile.PackageDetails, error) {
switch filename {
case "requirements.txt":
extractor := lockfile.RequirementsTxtExtractor{}
return extractor.Extract(depFile)
case "Pipfile.lock":
extractor := lockfile.PipenvLockExtractor{}
return extractor.Extract(depFile)
default:
return nil, fmt.Errorf("unsupported PyPI lockfile: %s", filename)
}
}
// ExtractorManager manages all ecosystem extractors
type ExtractorManager struct {
extractors map[packagev1.Ecosystem]EcosystemExtractor
}
func NewExtractorManager() *ExtractorManager {
return &ExtractorManager{
extractors: map[packagev1.Ecosystem]EcosystemExtractor{
packagev1.Ecosystem_ECOSYSTEM_NPM: &NpmExtractor{},
packagev1.Ecosystem_ECOSYSTEM_PYPI: &PyPiExtractor{},
},
}
}
func (em *ExtractorManager) GetExtractorForEcosystem(ecosystem packagev1.Ecosystem) (EcosystemExtractor, bool) {
extractor, exists := em.extractors[ecosystem]
return extractor, exists
}
func (em *ExtractorManager) GetSupportedFilesForEcosystem(ecosystem packagev1.Ecosystem) []string {
if extractor, exists := em.extractors[ecosystem]; exists {
return extractor.GetSupportedFiles()
}
return nil
}
func (em *ExtractorManager) GetAllSupportedFiles() []string {
var allFiles []string
for _, extractor := range em.extractors {
allFiles = append(allFiles, extractor.GetSupportedFiles()...)
}
return allFiles
}