mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
* Add support for yarn package manager - Added yarn command handler in cmd/npm/yarn.go - Added DefaultYarnPackageManagerConfig() in packagemanager/npm.go - Added yarn dev flag support (--dev/-D) in ParseCommand() - Added yarn analytics tracking in internal/analytics/event.go - Registered yarn command in main.go - Added yarn to alias setup in internal/alias/alias.go - Added comprehensive test suite in packagemanager/yarn_test.go - All tests passing (12 yarn tests + existing tests) Resolves #30 Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> * docs: update README with yarn package manager support Updated documentation to reflect yarn support addition: - Changed yarn status from '🚧 Planned' to '✅ Active' in package managers table - Added 'pmg yarn add <package>' command example - Added 'yarn add <package-name>' to command list - Added 'yarn install # Uses yarn.lock' to lockfile examples This documentation update corresponds to the yarn implementation in the previous commit. Related to #30 Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> * fix: address review feedback for yarn support - Add support for bare 'yarn' command as manifest install - Validate yarn install does not accept package names - Add YarnExtractor for yarn.lock file support Changes: - packagemanager/npm.go: Added bare yarn command handling and validation - packagemanager/yarn_test.go: Added test for bare yarn command - extractor/ecosystems.go: Added Yarn PackageManagerName and extractor - extractor/npm.go: Added YarnExtractor implementation - go.mod, go.sum: Updated dependencies Addresses review feedback from @Sahilb315 - Bare yarn command now triggers manifest install per docs - yarn install <package> is now properly rejected - yarn.lock extraction support added Related to #30 Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> * chore: tidy go.mod and go.sum to remove unused dependencies Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> * fix: add yarn.lock extractor mapping - Add yarn.lock case in getExtractorForFile switch - Import yarnlock extractor from osv-scalibr - Enables lockfile parsing for manifest-based installations Tested both package-based and manifest-based installations successfully. Addresses review feedback from @Sahilb315 Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> * test: add validation test for yarn install with package name - Add test case to verify 'yarn install <package>' is rejected - Ensures invalid syntax returns no install targets - Confirms IsManifestInstall is false for invalid commands Addresses review feedback from @Sahilb315 Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com> --------- Signed-off-by: shrvansudhakara <shrvansudhakara@gmail.com>
87 lines
2.5 KiB
Go
87 lines
2.5 KiB
Go
package extractor
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
|
|
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
|
|
"github.com/google/osv-scalibr/extractor/filesystem"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/bunlock"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/packagelockjson"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/pnpmlock"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/javascript/yarnlock"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/python/poetrylock"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/python/requirements"
|
|
"github.com/google/osv-scalibr/extractor/filesystem/language/python/uvlock"
|
|
"github.com/google/osv-scalibr/fs"
|
|
)
|
|
|
|
func getExtractorForFile(filename string) (filesystem.Extractor, error) {
|
|
filename = filepath.Base(filename)
|
|
|
|
// Regex for requirements files (match requirements.txt and requirements-{word}.txt)
|
|
reqPattern := regexp.MustCompile(`^requirements(?:-\w+)?\.txt$`)
|
|
|
|
switch {
|
|
case filename == "package-lock.json":
|
|
return packagelockjson.NewDefault(), nil
|
|
case filename == "pnpm-lock.yaml":
|
|
return pnpmlock.New(), nil
|
|
case filename == "bun.lock":
|
|
return bunlock.New(), nil
|
|
case filename == "yarn.lock":
|
|
return yarnlock.New(), nil
|
|
case reqPattern.MatchString(filename):
|
|
return requirements.NewDefault(), nil
|
|
case filename == "uv.lock":
|
|
return uvlock.New(), nil
|
|
case filename == "poetry.lock":
|
|
return poetrylock.New(), nil
|
|
default:
|
|
return nil, fmt.Errorf("unsupported lockfile type: %s", filename)
|
|
}
|
|
}
|
|
|
|
func parseLockfile(lockfilePath, scanDir string, ecosystem packagev1.Ecosystem) ([]*packagev1.PackageVersion, error) {
|
|
extractor, err := getExtractorForFile(lockfilePath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
file, err := os.Open(lockfilePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to open lockfile: %w", err)
|
|
}
|
|
defer file.Close()
|
|
|
|
inputConfig := &filesystem.ScanInput{
|
|
FS: fs.DirFS(scanDir),
|
|
Path: lockfilePath,
|
|
Reader: file,
|
|
}
|
|
|
|
inventory, err := extractor.Extract(context.Background(), inputConfig)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to extract packages: %w", err)
|
|
}
|
|
|
|
var packages []*packagev1.PackageVersion
|
|
|
|
for _, invPkg := range inventory.Packages {
|
|
pkg := &packagev1.PackageVersion{
|
|
Package: &packagev1.Package{
|
|
Name: invPkg.Name,
|
|
Ecosystem: ecosystem,
|
|
},
|
|
Version: invPkg.Version,
|
|
}
|
|
|
|
packages = append(packages, pkg)
|
|
}
|
|
|
|
return packages, nil
|
|
}
|