diff --git a/cmd/ossprey/main.go b/cmd/ossprey/main.go index 12088de..4ecfcce 100644 --- a/cmd/ossprey/main.go +++ b/cmd/ossprey/main.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "os/exec" + "runtime/debug" "github.com/spf13/cobra" @@ -21,6 +22,13 @@ var version = "0.0.0-dev" const defaultAPIURL = "https://api.ossprey.com" func main() { + defer func() { + if r := recover(); r != nil { + fmt.Fprintf(os.Stderr, "ossprey: fatal: %v\n%s\n", r, debug.Stack()) + os.Exit(2) + } + }() + root := &cobra.Command{ Use: "ossprey", Short: "Ossprey supply-chain scanner", diff --git a/internal/catalog/cataloger.go b/internal/catalog/cataloger.go index 4f792a9..ee51ae8 100644 --- a/internal/catalog/cataloger.go +++ b/internal/catalog/cataloger.go @@ -3,6 +3,7 @@ package catalog import ( "fmt" "path/filepath" + "strings" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" @@ -11,6 +12,11 @@ import ( // fileParser converts one matched manifest into syft packages. type fileParser func(absPath string, loc file.Location) ([]pkg.Package, error) +// isVendoredPath reports whether p sits inside a vendored dependency tree. +func isVendoredPath(p string) bool { + return strings.Contains(p, "node_modules/") +} + // catalogByGlob runs parse against every file matching glob under the // resolver's root, dedup'd by (name, version). Shared by every ossprey-* // cataloger — they differ only by glob + parse. @@ -22,6 +28,10 @@ func catalogByGlob(resolver file.Resolver, root, glob, label string, parse fileP seen := make(map[string]struct{}) var out []pkg.Package for _, loc := range locs { + // Skip vendored dependencies. + if isVendoredPath(loc.RealPath) { + continue + } pkgs, err := parse(filepath.Join(root, loc.RealPath), loc) if err != nil || len(pkgs) == 0 { continue