Compare commits

...
Author SHA1 Message Date
Alex Goodman 02b7c959c7 redefine unknown dependency completeness enum
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-12-05 09:47:02 -05:00
Alex Goodman b64213109a rename mixed enum and fix golang
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-11-22 17:25:29 -05:00
Alex Goodman ad2abfabd1 update formatter and json schema
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-11-15 11:21:21 -05:00
Alex Goodman 5b7ec60f8d add package dependency quality notes
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-11-15 09:51:20 -05:00
118 changed files with 5743 additions and 2309 deletions
+1 -1
View File
@@ -3,5 +3,5 @@ package internal
const ( const (
// JSONSchemaVersion is the current schema version output by the JSON encoder // JSONSchemaVersion is the current schema version output by the JSON encoder
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment. // This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
JSONSchemaVersion = "16.0.18" JSONSchemaVersion = "16.0.19"
) )
+9
View File
@@ -110,6 +110,8 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
pkgs, relationships = applyCompliance(cfg.ComplianceConfig, pkgs, relationships) pkgs, relationships = applyCompliance(cfg.ComplianceConfig, pkgs, relationships)
finalizeDependencyCompleteness(pkgs)
sbom.AddPackages(pkgs...) sbom.AddPackages(pkgs...)
sbom.AddRelationships(relationships...) sbom.AddRelationships(relationships...)
t.Add(int64(len(pkgs))) t.Add(int64(len(pkgs)))
@@ -124,6 +126,13 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
return NewTask(c.Name(), fn, tags...) return NewTask(c.Name(), fn, tags...)
} }
func finalizeDependencyCompleteness(pkgs []pkg.Package) {
// ensure that all packages have a non-empty dependency list
for i := range pkgs {
pkgs[i].Dependencies = pkg.ParseDependencyCompleteness(string(pkgs[i].Dependencies))
}
}
func finalizePkgCatalogerResults(cfg CatalogingFactoryConfig, resolver file.PathResolver, catalogerName string, pkgs []pkg.Package, relationships []artifact.Relationship) ([]pkg.Package, []artifact.Relationship) { func finalizePkgCatalogerResults(cfg CatalogingFactoryConfig, resolver file.PathResolver, catalogerName string, pkgs []pkg.Package, relationships []artifact.Relationship) ([]pkg.Package, []artifact.Relationship) {
for i, p := range pkgs { for i, p := range pkgs {
if p.FoundBy == "" { if p.FoundBy == "" {
File diff suppressed because it is too large Load Diff
+6 -2
View File
@@ -1,6 +1,6 @@
{ {
"$schema": "https://json-schema.org/draft/2020-12/schema", "$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "anchore.io/schema/syft/json/16.0.18/document", "$id": "anchore.io/schema/syft/json/16.0.19/document",
"$ref": "#/$defs/Document", "$ref": "#/$defs/Document",
"$defs": { "$defs": {
"AlpmDbEntry": { "AlpmDbEntry": {
@@ -1610,6 +1610,9 @@
"purl": { "purl": {
"type": "string" "type": "string"
}, },
"dependencies": {
"type": "string"
},
"metadataType": { "metadataType": {
"type": "string" "type": "string"
}, },
@@ -1773,7 +1776,8 @@
"licenses", "licenses",
"language", "language",
"cpes", "cpes",
"purl" "purl",
"dependencies"
] ]
}, },
"PhpComposerAuthors": { "PhpComposerAuthors": {
@@ -121,7 +121,8 @@ func newDirectoryCatalog() *pkg.Collection {
}, },
}, },
}, },
PURL: "a-purl-2", // intentionally a bad pURL for test fixtures PURL: "a-purl-2", // intentionally a bad pURL for test fixtures
Dependencies: pkg.CompleteDependencies,
CPEs: []cpe.CPE{ CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")), cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
}, },
@@ -138,7 +139,8 @@ func newDirectoryCatalog() *pkg.Collection {
Package: "package-2", Package: "package-2",
Version: "2.0.1", Version: "2.0.1",
}, },
PURL: "pkg:deb/debian/package-2@2.0.1", PURL: "pkg:deb/debian/package-2@2.0.1",
Dependencies: pkg.CompleteDependencies,
CPEs: []cpe.CPE{ CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")), cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
}, },
@@ -163,6 +165,7 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT"), pkg.NewLicense("MIT"),
), ),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "package-1", Name: "package-1",
Version: "1.0.1", Version: "1.0.1",
@@ -190,7 +193,8 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
Package: "package-2", Package: "package-2",
Version: "2.0.1", Version: "2.0.1",
}, },
PURL: "pkg:deb/debian/package-2@2.0.1", Dependencies: pkg.CompleteDependencies,
PURL: "pkg:deb/debian/package-2@2.0.1",
CPEs: []cpe.CPE{ CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", "another-test-source"), cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", "another-test-source"),
}, },
+4 -2
View File
@@ -117,7 +117,8 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
Name: "package-1", Name: "package-1",
Version: "1.0.1", Version: "1.0.1",
}, },
PURL: "a-purl-1", // intentionally a bad pURL for test fixtures PURL: "a-purl-1", // intentionally a bad pURL for test fixtures
Dependencies: pkg.CompleteDependencies,
CPEs: []cpe.CPE{ CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", cpe.GeneratedSource), cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", cpe.GeneratedSource),
}, },
@@ -137,7 +138,8 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
Package: "package-2", Package: "package-2",
Version: "2.0.1", Version: "2.0.1",
}, },
PURL: "pkg:deb/debian/package-2@2.0.1", PURL: "pkg:deb/debian/package-2@2.0.1",
Dependencies: pkg.CompleteDependencies,
CPEs: []cpe.CPE{ CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
}, },
+8 -6
View File
@@ -141,10 +141,11 @@ func TestEncodeFullJSONDocument(t *testing.T) {
RealPath: "/a/place/a", RealPath: "/a/place/a",
}), }),
), ),
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
FoundBy: "the-cataloger-1", FoundBy: "the-cataloger-1",
Language: pkg.Python, Language: pkg.Python,
Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "package-1", Name: "package-1",
Version: "1.0.1", Version: "1.0.1",
@@ -164,8 +165,9 @@ func TestEncodeFullJSONDocument(t *testing.T) {
RealPath: "/b/place/b", RealPath: "/b/place/b",
}), }),
), ),
Type: pkg.DebPkg, Type: pkg.DebPkg,
FoundBy: "the-cataloger-2", FoundBy: "the-cataloger-2",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DpkgDBEntry{ Metadata: pkg.DpkgDBEntry{
Package: "package-2", Package: "package-2",
Version: "2.0.1", Version: "2.0.1",
+11 -10
View File
@@ -24,16 +24,17 @@ type Package struct {
// PackageBasicData contains non-ambiguous values (type-wise) from pkg.Package. // PackageBasicData contains non-ambiguous values (type-wise) from pkg.Package.
type PackageBasicData struct { type PackageBasicData struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Version string `json:"version"` Version string `json:"version"`
Type pkg.Type `json:"type"` Type pkg.Type `json:"type"`
FoundBy string `json:"foundBy"` FoundBy string `json:"foundBy"`
Locations []file.Location `json:"locations"` Locations []file.Location `json:"locations"`
Licenses licenses `json:"licenses"` Licenses licenses `json:"licenses"`
Language pkg.Language `json:"language"` Language pkg.Language `json:"language"`
CPEs cpes `json:"cpes"` CPEs cpes `json:"cpes"`
PURL string `json:"purl"` PURL string `json:"purl"`
Dependencies pkg.DependencyCompleteness `json:"dependencies"`
} }
type cpes []CPE type cpes []CPE
@@ -28,6 +28,7 @@
} }
], ],
"purl": "a-purl-2", "purl": "a-purl-2",
"dependencies": "complete",
"metadataType": "python-package", "metadataType": "python-package",
"metadata": { "metadata": {
"name": "package-1", "name": "package-1",
@@ -63,6 +64,7 @@
} }
], ],
"purl": "pkg:deb/debian/package-2@2.0.1", "purl": "pkg:deb/debian/package-2@2.0.1",
"dependencies": "complete",
"metadataType": "dpkg-db-entry", "metadataType": "dpkg-db-entry",
"metadata": { "metadata": {
"package": "package-2", "package": "package-2",
@@ -29,6 +29,7 @@
} }
], ],
"purl": "a-purl-1", "purl": "a-purl-1",
"dependencies": "complete",
"metadataType": "python-package", "metadataType": "python-package",
"metadata": { "metadata": {
"name": "package-1", "name": "package-1",
@@ -60,6 +61,7 @@
} }
], ],
"purl": "a-purl-2", "purl": "a-purl-2",
"dependencies": "complete",
"metadataType": "dpkg-db-entry", "metadataType": "dpkg-db-entry",
"metadata": { "metadata": {
"package": "package-2", "package": "package-2",
@@ -30,6 +30,7 @@
} }
], ],
"purl": "a-purl-1", "purl": "a-purl-1",
"dependencies": "complete",
"metadataType": "python-package", "metadataType": "python-package",
"metadata": { "metadata": {
"name": "package-1", "name": "package-1",
@@ -62,6 +63,7 @@
} }
], ],
"purl": "pkg:deb/debian/package-2@2.0.1", "purl": "pkg:deb/debian/package-2@2.0.1",
"dependencies": "complete",
"metadataType": "dpkg-db-entry", "metadataType": "dpkg-db-entry",
"metadata": { "metadata": {
"package": "package-2", "package": "package-2",
+11 -10
View File
@@ -259,16 +259,17 @@ func toPackageModel(p pkg.Package, cfg EncoderConfig) model.Package {
return model.Package{ return model.Package{
PackageBasicData: model.PackageBasicData{ PackageBasicData: model.PackageBasicData{
ID: string(p.ID()), ID: string(p.ID()),
Name: p.Name, Name: p.Name,
Version: p.Version, Version: p.Version,
Type: p.Type, Type: p.Type,
FoundBy: p.FoundBy, FoundBy: p.FoundBy,
Locations: p.Locations.ToSlice(), Locations: p.Locations.ToSlice(),
Licenses: licenses, Licenses: licenses,
Language: p.Language, Language: p.Language,
CPEs: cpes, CPEs: cpes,
PURL: p.PURL, PURL: p.PURL,
Dependencies: p.Dependencies,
}, },
PackageCustomData: model.PackageCustomData{ PackageCustomData: model.PackageCustomData{
MetadataType: metadataType(p.Metadata, cfg.Legacy), MetadataType: metadataType(p.Metadata, cfg.Legacy),
+11 -10
View File
@@ -338,16 +338,17 @@ func toSyftPackage(p model.Package, idAliases map[string]string) pkg.Package {
} }
out := pkg.Package{ out := pkg.Package{
Name: p.Name, Name: p.Name,
Version: p.Version, Version: p.Version,
FoundBy: p.FoundBy, FoundBy: p.FoundBy,
Locations: file.NewLocationSet(p.Locations...), Locations: file.NewLocationSet(p.Locations...),
Licenses: pkg.NewLicenseSet(toSyftLicenses(p.Licenses)...), Licenses: pkg.NewLicenseSet(toSyftLicenses(p.Licenses)...),
Language: p.Language, Language: p.Language,
Type: p.Type, Type: p.Type,
CPEs: cpes, CPEs: cpes,
PURL: p.PURL, PURL: p.PURL,
Metadata: p.Metadata, Dependencies: p.Dependencies,
Metadata: p.Metadata,
} }
// we don't know if this package ID is truly unique, however, we need to trust the user input in case there are // we don't know if this package ID is truly unique, however, we need to trust the user input in case there are
+8 -4
View File
@@ -23,7 +23,8 @@ func TestApkDBCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("GPL-3.0-or-later", dbLocation), pkg.NewLicenseFromLocations("GPL-3.0-or-later", dbLocation),
), ),
Locations: file.NewLocationSet(dbLocation), Locations: file.NewLocationSet(dbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "bash", Package: "bash",
OriginPackage: "bash", OriginPackage: "bash",
@@ -52,7 +53,8 @@ func TestApkDBCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("GPL-2.0-only", dbLocation), pkg.NewLicenseFromLocations("GPL-2.0-only", dbLocation),
), ),
Locations: file.NewLocationSet(dbLocation), Locations: file.NewLocationSet(dbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "busybox-binsh", Package: "busybox-binsh",
OriginPackage: "busybox", OriginPackage: "busybox",
@@ -81,7 +83,8 @@ func TestApkDBCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", dbLocation), pkg.NewLicenseFromLocations("MIT", dbLocation),
), ),
Locations: file.NewLocationSet(dbLocation), Locations: file.NewLocationSet(dbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "musl", Package: "musl",
OriginPackage: "musl", OriginPackage: "musl",
@@ -108,7 +111,8 @@ func TestApkDBCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("GPL-2.0-or-later", dbLocation), pkg.NewLicenseFromLocations("GPL-2.0-or-later", dbLocation),
), ),
Locations: file.NewLocationSet(dbLocation), Locations: file.NewLocationSet(dbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "readline", Package: "readline",
OriginPackage: "readline", OriginPackage: "readline",
+8 -7
View File
@@ -20,13 +20,14 @@ func newPackage(d parsedData, release *linux.Release, dbLocation file.Location)
} }
p := pkg.Package{ p := pkg.Package{
Name: d.Package, Name: d.Package,
Version: d.Version, Version: d.Version,
Locations: file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation, licenseStrings...)...), Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation, licenseStrings...)...),
PURL: packageURL(d.ApkDBEntry, release), PURL: packageURL(d.ApkDBEntry, release),
Type: pkg.ApkPkg, Type: pkg.ApkPkg,
Metadata: d.ApkDBEntry, Dependencies: pkg.CompleteDependencies,
Metadata: d.ApkDBEntry,
} }
p.SetID() p.SetID()
@@ -90,7 +90,8 @@ func TestSinglePackageDetails(t *testing.T) {
pkg.NewLicense("BSD"), pkg.NewLicense("BSD"),
pkg.NewLicense("GPL2+"), pkg.NewLicense("GPL2+"),
), ),
Type: pkg.ApkPkg, Type: pkg.ApkPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "musl-utils", Package: "musl-utils",
OriginPackage: "musl", OriginPackage: "musl",
@@ -177,7 +178,8 @@ func TestSinglePackageDetails(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicense("GPL-2.0-only"), pkg.NewLicense("GPL-2.0-only"),
), ),
Type: pkg.ApkPkg, Type: pkg.ApkPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "alpine-baselayout-data", Package: "alpine-baselayout-data",
OriginPackage: "alpine-baselayout", OriginPackage: "alpine-baselayout",
@@ -221,8 +223,8 @@ func TestSinglePackageDetails(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicense("GPL-2.0-only"), pkg.NewLicense("GPL-2.0-only"),
), ),
Type: pkg.ApkPkg, Type: pkg.ApkPkg,
PURL: "", Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ApkDBEntry{ Metadata: pkg.ApkDBEntry{
Package: "alpine-baselayout", Package: "alpine-baselayout",
OriginPackage: "alpine-baselayout", OriginPackage: "alpine-baselayout",
+12 -7
View File
@@ -34,7 +34,8 @@ func TestAlpmCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", treeSitterDbLocation), pkg.NewLicenseFromLocations("MIT", treeSitterDbLocation),
), ),
Locations: file.NewLocationSet(treeSitterDbLocation), Locations: file.NewLocationSet(treeSitterDbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.AlpmDBEntry{ Metadata: pkg.AlpmDBEntry{
BasePackage: "tree-sitter", BasePackage: "tree-sitter",
Package: "tree-sitter", Package: "tree-sitter",
@@ -60,7 +61,8 @@ func TestAlpmCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("GPL3", emacsDbLocation), pkg.NewLicenseFromLocations("GPL3", emacsDbLocation),
), ),
Locations: file.NewLocationSet(emacsDbLocation), Locations: file.NewLocationSet(emacsDbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.AlpmDBEntry{ Metadata: pkg.AlpmDBEntry{
BasePackage: "emacs", BasePackage: "emacs",
Package: "emacs", Package: "emacs",
@@ -86,6 +88,7 @@ func TestAlpmCataloger(t *testing.T) {
fuzzyDbLocation, fuzzyDbLocation,
file.NewLocation("var/lib/pacman/local/fuzzy-1.2-3/files"), file.NewLocation("var/lib/pacman/local/fuzzy-1.2-3/files"),
), ),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.AlpmDBEntry{ Metadata: pkg.AlpmDBEntry{
Package: "fuzzy", Package: "fuzzy",
Version: "1.2-3", Version: "1.2-3",
@@ -103,11 +106,12 @@ func TestAlpmCataloger(t *testing.T) {
} }
madeupPkg := pkg.Package{ madeupPkg := pkg.Package{
Name: "madeup", Name: "madeup",
Version: "20.30-4", Version: "20.30-4",
Type: pkg.AlpmPkg, Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger", FoundBy: "alpm-db-cataloger",
Locations: file.NewLocationSet(madeupDbLocation), Locations: file.NewLocationSet(madeupDbLocation),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.AlpmDBEntry{ Metadata: pkg.AlpmDBEntry{
Package: "madeup", Package: "madeup",
Version: "20.30-4", Version: "20.30-4",
@@ -131,6 +135,7 @@ func TestAlpmCataloger(t *testing.T) {
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/files"), file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/files"),
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/mtree"), file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/mtree"),
), ),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.AlpmDBEntry{ Metadata: pkg.AlpmDBEntry{
BasePackage: "gmp", BasePackage: "gmp",
Package: "gmp", Package: "gmp",
+8 -7
View File
@@ -16,13 +16,14 @@ func newPackage(m *parsedData, release *linux.Release, dbLocation file.Location,
locs.Add(otherLocations...) locs.Add(otherLocations...)
p := pkg.Package{ p := pkg.Package{
Name: m.Package, Name: m.Package,
Version: m.Version, Version: m.Version,
Locations: locs, Locations: locs,
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation.WithoutAnnotations(), licenseCandidates...)...), Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation.WithoutAnnotations(), licenseCandidates...)...),
Type: pkg.AlpmPkg, Type: pkg.AlpmPkg,
PURL: packageURL(m, release), PURL: packageURL(m, release),
Metadata: m.AlpmDBEntry, Dependencies: pkg.CompleteDependencies,
Metadata: m.AlpmDBEntry,
} }
p.SetID() p.SetID()
@@ -35,6 +35,9 @@ func newClassifierPackage(classifier Classifier, location file.Location, matchMe
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
CPEs: cpes, CPEs: cpes,
FoundBy: catalogerName, FoundBy: catalogerName,
// classifiers are limited to identifying package identities, but have no information about dependencies.
// Furthermore, we have no understanding about the mechanisms for dependency resolution for these packages.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.BinarySignature{ Metadata: pkg.BinarySignature{
Matches: []pkg.ClassifierMatch{ Matches: []pkg.ClassifierMatch{
{ {
+4 -1
View File
@@ -16,7 +16,10 @@ func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet) p
PURL: packageURL(metadata), PURL: packageURL(metadata),
Type: pkgType(metadata.Type), Type: pkgType(metadata.Type),
Locations: locations, Locations: locations,
Metadata: metadata.ELFBinaryPackageNoteJSONPayload, // though we can look for shared libs, we cannot see static dependencies nor dynamic dependencies using dlopen.
// this means that, even in cases where the dep info is actually complete, we can't programmatically determine that.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: metadata.ELFBinaryPackageNoteJSONPayload,
} }
p.SetID() p.SetID()
@@ -35,7 +35,8 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"}, pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"},
), ),
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "testfixture", Type: "testfixture",
Vendor: "syft", Vendor: "syft",
@@ -56,7 +57,8 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"}, pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"},
), ),
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "testfixture", Type: "testfixture",
Vendor: "syft", Vendor: "syft",
@@ -80,8 +82,9 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Licenses: pkg.NewLicenseSet(), Licenses: pkg.NewLicenseSet(),
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "rpm", Type: "rpm",
Architecture: "x86_64", Architecture: "x86_64",
@@ -102,8 +105,9 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Licenses: pkg.NewLicenseSet(), Licenses: pkg.NewLicenseSet(),
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "rpm", Type: "rpm",
Architecture: "arm", Architecture: "arm",
@@ -154,10 +154,11 @@ func Test_newELFPackage(t *testing.T) {
}, },
expected: pkg.Package{ expected: pkg.Package{
Name: "syfttestfixture", Name: "syfttestfixture",
Version: "0.01", Version: "0.01",
Type: "binary", Type: "binary",
PURL: "pkg:generic/syftsys/syfttestfixture@0.01", PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "binary", Type: "binary",
System: "syftsys", System: "syftsys",
+22 -14
View File
@@ -67,35 +67,43 @@ func splitConanRef(ref string) *conanRef {
} }
func newConanfilePackage(m pkg.ConanfileEntry, locations ...file.Location) *pkg.Package { func newConanfilePackage(m pkg.ConanfileEntry, locations ...file.Location) *pkg.Package {
return newConanPackage(m.Ref, m, locations...) // though a conanfile is a listing of direct dependencies, we are not capturing these today, so are forced to answer unknown
return newConanPackage(m.Ref, m, pkg.UnknownDependencyCompleteness, locations...)
} }
func newConanlockPackage(m pkg.ConanV1LockEntry, locations ...file.Location) *pkg.Package { func newConanlockV1Package(m pkg.ConanV1LockEntry, locations ...file.Location) *pkg.Package {
return newConanPackage(m.Ref, m, locations...) // conan.lock is primarily used to lock the dependency graph at specific versions to ensure consistent builds,
// and the dependency tree can be inferred from the contents (distinguishing between direct and transitive dependencies)
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
} }
func newConanReferencePackage(m pkg.ConanV2LockEntry, locations ...file.Location) *pkg.Package { func newConanLockv2Package(m pkg.ConanV2LockEntry, locations ...file.Location) *pkg.Package {
return newConanPackage(m.Ref, m, locations...) // conan.lock is primarily used to lock the dependency graph at specific versions to ensure consistent builds,
// and the dependency tree can be inferred from the contents (distinguishing between direct and transitive dependencies)
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
} }
func newConaninfoPackage(m pkg.ConaninfoEntry, locations ...file.Location) *pkg.Package { func newConaninfoPackage(m pkg.ConaninfoEntry, locations ...file.Location) *pkg.Package {
return newConanPackage(m.Ref, m, locations...) // conaninfo.txt is generated during the build and contains detailed information about the entire dependency tree,
// and today the codebase does infer direct dependencies from this source
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
} }
func newConanPackage(refStr string, metadata any, locations ...file.Location) *pkg.Package { func newConanPackage(refStr string, metadata any, dep pkg.DependencyCompleteness, locations ...file.Location) *pkg.Package {
ref := splitConanRef(refStr) ref := splitConanRef(refStr)
if ref == nil { if ref == nil {
return nil return nil
} }
p := pkg.Package{ p := pkg.Package{
Name: ref.Name, Name: ref.Name,
Version: ref.Version, Version: ref.Version,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(ref), PURL: packageURL(ref),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Metadata: metadata, Dependencies: dep,
Metadata: metadata,
} }
p.SetID() p.SetID()
+3 -1
View File
@@ -22,11 +22,12 @@ func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment,
r := bufio.NewReader(reader) r := bufio.NewReader(reader)
inRequirements := false inRequirements := false
var pkgs []pkg.Package var pkgs []pkg.Package
loop:
for { for {
line, err := r.ReadString('\n') line, err := r.ReadString('\n')
switch { switch {
case errors.Is(err, io.EOF): case errors.Is(err, io.EOF):
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages") break loop
case err != nil: case err != nil:
return nil, nil, fmt.Errorf("failed to parse conanfile.txt file: %w", err) return nil, nil, fmt.Errorf("failed to parse conanfile.txt file: %w", err)
} }
@@ -56,4 +57,5 @@ func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment,
pkgs = append(pkgs, *p) pkgs = append(pkgs, *p)
} }
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
} }
+42 -36
View File
@@ -14,67 +14,73 @@ func TestParseConanfile(t *testing.T) {
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture)) fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "catch2", Name: "catch2",
Version: "2.13.8", Version: "2.13.8",
PURL: "pkg:conan/catch2@2.13.8", PURL: "pkg:conan/catch2@2.13.8",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "catch2/2.13.8", Ref: "catch2/2.13.8",
}, },
}, },
{ {
Name: "docopt.cpp", Name: "docopt.cpp",
Version: "0.6.3", Version: "0.6.3",
PURL: "pkg:conan/docopt.cpp@0.6.3", PURL: "pkg:conan/docopt.cpp@0.6.3",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "docopt.cpp/0.6.3", Ref: "docopt.cpp/0.6.3",
}, },
}, },
{ {
Name: "fmt", Name: "fmt",
Version: "8.1.1", Version: "8.1.1",
PURL: "pkg:conan/fmt@8.1.1", PURL: "pkg:conan/fmt@8.1.1",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "fmt/8.1.1", Ref: "fmt/8.1.1",
}, },
}, },
{ {
Name: "spdlog", Name: "spdlog",
Version: "1.9.2", Version: "1.9.2",
PURL: "pkg:conan/my_user/spdlog@1.9.2?channel=my_channel", PURL: "pkg:conan/my_user/spdlog@1.9.2?channel=my_channel",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "spdlog/1.9.2@my_user/my_channel#1234567%%987654", Ref: "spdlog/1.9.2@my_user/my_channel#1234567%%987654",
}, },
}, },
{ {
Name: "sdl", Name: "sdl",
Version: "2.0.20", Version: "2.0.20",
PURL: "pkg:conan/sdl@2.0.20", PURL: "pkg:conan/sdl@2.0.20",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "sdl/2.0.20#1234567%%987654", Ref: "sdl/2.0.20#1234567%%987654",
}, },
}, },
{ {
Name: "fltk", Name: "fltk",
Version: "1.3.8", Version: "1.3.8",
PURL: "pkg:conan/my_user/fltk@1.3.8?channel=my_channel", PURL: "pkg:conan/my_user/fltk@1.3.8?channel=my_channel",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ConanfileEntry{ Metadata: pkg.ConanfileEntry{
Ref: "fltk/1.3.8@my_user/my_channel", Ref: "fltk/1.3.8@my_user/my_channel",
}, },
+42 -36
View File
@@ -13,72 +13,78 @@ func TestParseConaninfo(t *testing.T) {
fixture := "test-fixtures/conaninfo/mfast/1.2.2/my_user/my_channel/package/9d1f076b471417647c2022a78d5e2c1f834289ac/conaninfo.txt" fixture := "test-fixtures/conaninfo/mfast/1.2.2/my_user/my_channel/package/9d1f076b471417647c2022a78d5e2c1f834289ac/conaninfo.txt"
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "mfast", Name: "mfast",
Version: "1.2.2", Version: "1.2.2",
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel", PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39", Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
PackageID: "9d1f076b471417647c2022a78d5e2c1f834289ac", PackageID: "9d1f076b471417647c2022a78d5e2c1f834289ac",
}, },
}, },
{ {
Name: "boost", Name: "boost",
Version: "1.75.0", Version: "1.75.0",
PURL: "pkg:conan/boost@1.75.0", PURL: "pkg:conan/boost@1.75.0",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "boost/1.75.0:dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978", Ref: "boost/1.75.0:dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
PackageID: "dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978", PackageID: "dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
}, },
}, },
{ {
Name: "zlib", Name: "zlib",
Version: "1.2.13", Version: "1.2.13",
PURL: "pkg:conan/zlib@1.2.13", PURL: "pkg:conan/zlib@1.2.13",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "zlib/1.2.13:dfbe50feef7f3c6223a476cd5aeadb687084a646", Ref: "zlib/1.2.13:dfbe50feef7f3c6223a476cd5aeadb687084a646",
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646", PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
}, },
}, },
{ {
Name: "bzip2", Name: "bzip2",
Version: "1.0.8", Version: "1.0.8",
PURL: "pkg:conan/bzip2@1.0.8", PURL: "pkg:conan/bzip2@1.0.8",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "bzip2/1.0.8:c32092bf4d4bb47cf962af898e02823f499b017e", Ref: "bzip2/1.0.8:c32092bf4d4bb47cf962af898e02823f499b017e",
PackageID: "c32092bf4d4bb47cf962af898e02823f499b017e", PackageID: "c32092bf4d4bb47cf962af898e02823f499b017e",
}, },
}, },
{ {
Name: "libbacktrace", Name: "libbacktrace",
Version: "cci.20210118", Version: "cci.20210118",
PURL: "pkg:conan/libbacktrace@cci.20210118", PURL: "pkg:conan/libbacktrace@cci.20210118",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "libbacktrace/cci.20210118:dfbe50feef7f3c6223a476cd5aeadb687084a646", Ref: "libbacktrace/cci.20210118:dfbe50feef7f3c6223a476cd5aeadb687084a646",
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646", PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
}, },
}, },
{ {
Name: "tinyxml2", Name: "tinyxml2",
Version: "9.0.0", Version: "9.0.0",
PURL: "pkg:conan/tinyxml2@9.0.0", PURL: "pkg:conan/tinyxml2@9.0.0",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConaninfoEntry{ Metadata: pkg.ConaninfoEntry{
Ref: "tinyxml2/9.0.0:6557f18ca99c0b6a233f43db00e30efaa525e27e", Ref: "tinyxml2/9.0.0:6557f18ca99c0b6a233f43db00e30efaa525e27e",
PackageID: "6557f18ca99c0b6a233f43db00e30efaa525e27e", PackageID: "6557f18ca99c0b6a233f43db00e30efaa525e27e",
+2 -2
View File
@@ -89,7 +89,7 @@ func handleConanLockV1(cl conanLock, reader file.LocationReadCloser, parsedPkgRe
Prev: node.Prev, Prev: node.Prev,
} }
p := newConanlockPackage( p := newConanlockV1Package(
metadata, metadata,
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
) )
@@ -113,7 +113,7 @@ func handleConanLockV2(cl conanLock, reader file.LocationReadCloser, indexToPkgM
continue continue
} }
p := newConanReferencePackage( p := newConanLockv2Package(
reference, reference,
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
) )
+56 -48
View File
@@ -13,12 +13,13 @@ func TestParseConanLock(t *testing.T) {
fixture := "test-fixtures/conan.lock" fixture := "test-fixtures/conan.lock"
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "mfast", Name: "mfast",
Version: "1.2.2", Version: "1.2.2",
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel", PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39", Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
Options: pkg.KeyValues{ Options: pkg.KeyValues{
@@ -104,12 +105,13 @@ func TestParseConanLock(t *testing.T) {
}, },
}, },
{ {
Name: "boost", Name: "boost",
Version: "1.75.0", Version: "1.75.0",
PURL: "pkg:conan/boost@1.75.0", PURL: "pkg:conan/boost@1.75.0",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "boost/1.75.0#a9c318f067216f900900e044e7af4ab1", Ref: "boost/1.75.0#a9c318f067216f900900e044e7af4ab1",
Options: pkg.KeyValues{ Options: pkg.KeyValues{
@@ -190,12 +192,13 @@ func TestParseConanLock(t *testing.T) {
}, },
}, },
{ {
Name: "zlib", Name: "zlib",
Version: "1.2.12", Version: "1.2.12",
PURL: "pkg:conan/zlib@1.2.12", PURL: "pkg:conan/zlib@1.2.12",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "zlib/1.2.12#c67ce17f2e96b972d42393ce50a76a1a", Ref: "zlib/1.2.12#c67ce17f2e96b972d42393ce50a76a1a",
Options: pkg.KeyValues{ Options: pkg.KeyValues{
@@ -214,12 +217,13 @@ func TestParseConanLock(t *testing.T) {
}, },
}, },
{ {
Name: "bzip2", Name: "bzip2",
Version: "1.0.8", Version: "1.0.8",
PURL: "pkg:conan/bzip2@1.0.8", PURL: "pkg:conan/bzip2@1.0.8",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "bzip2/1.0.8#62a8031289639043797cf53fa876d0ef", Ref: "bzip2/1.0.8#62a8031289639043797cf53fa876d0ef",
Options: []pkg.KeyValue{ Options: []pkg.KeyValue{
@@ -242,12 +246,13 @@ func TestParseConanLock(t *testing.T) {
}, },
}, },
{ {
Name: "libbacktrace", Name: "libbacktrace",
Version: "cci.20210118", Version: "cci.20210118",
PURL: "pkg:conan/libbacktrace@cci.20210118", PURL: "pkg:conan/libbacktrace@cci.20210118",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "libbacktrace/cci.20210118#76e40b760e0bcd602d46db56b22820ab", Ref: "libbacktrace/cci.20210118#76e40b760e0bcd602d46db56b22820ab",
Options: []pkg.KeyValue{ Options: []pkg.KeyValue{
@@ -266,12 +271,13 @@ func TestParseConanLock(t *testing.T) {
}, },
}, },
{ {
Name: "tinyxml2", Name: "tinyxml2",
Version: "9.0.0", Version: "9.0.0",
PURL: "pkg:conan/tinyxml2@9.0.0", PURL: "pkg:conan/tinyxml2@9.0.0",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV1LockEntry{ Metadata: pkg.ConanV1LockEntry{
Ref: "tinyxml2/9.0.0#9f13a36ebfc222cd55fe531a0a8d94d1", Ref: "tinyxml2/9.0.0#9f13a36ebfc222cd55fe531a0a8d94d1",
Options: []pkg.KeyValue{ Options: []pkg.KeyValue{
@@ -337,12 +343,13 @@ func TestParseConanLockV2(t *testing.T) {
fixture := "test-fixtures/conanlock-v2/conan.lock" fixture := "test-fixtures/conanlock-v2/conan.lock"
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "matrix", Name: "matrix",
Version: "1.1", Version: "1.1",
PURL: "pkg:conan/matrix@1.1", PURL: "pkg:conan/matrix@1.1",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV2LockEntry{ Metadata: pkg.ConanV2LockEntry{
Ref: "matrix/1.1#905c3f0babc520684c84127378fefdd0%1675278901.7527816", Ref: "matrix/1.1#905c3f0babc520684c84127378fefdd0%1675278901.7527816",
RecipeRevision: "905c3f0babc520684c84127378fefdd0", RecipeRevision: "905c3f0babc520684c84127378fefdd0",
@@ -350,12 +357,13 @@ func TestParseConanLockV2(t *testing.T) {
}, },
}, },
{ {
Name: "sound32", Name: "sound32",
Version: "1.0", Version: "1.0",
PURL: "pkg:conan/sound32@1.0", PURL: "pkg:conan/sound32@1.0",
Locations: file.NewLocationSet(file.NewLocation(fixture)), Locations: file.NewLocationSet(file.NewLocation(fixture)),
Language: pkg.CPP, Language: pkg.CPP,
Type: pkg.ConanPkg, Type: pkg.ConanPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.ConanV2LockEntry{ Metadata: pkg.ConanV2LockEntry{
Ref: "sound32/1.0#83d4b7bf607b3b60a6546f8b58b5cdd7%1675278904.0791488", Ref: "sound32/1.0#83d4b7bf607b3b60a6546f8b58b5cdd7%1675278904.0791488",
RecipeRevision: "83d4b7bf607b3b60a6546f8b58b5cdd7", RecipeRevision: "83d4b7bf607b3b60a6546f8b58b5cdd7",
+3 -1
View File
@@ -21,7 +21,9 @@ func newPubspecLockPackage(name string, raw pubspecLockPackage, locations ...fil
PURL: packageURL(metadata), PURL: packageURL(metadata),
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Metadata: metadata, // since we capture no dependencies today we know that the dep info is unknown
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: metadata,
} }
p.SetID() p.SetID()
@@ -14,12 +14,13 @@ func TestParsePubspecLock(t *testing.T) {
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture)) fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "ale", Name: "ale",
Version: "3.3.0", Version: "3.3.0",
PURL: "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org", PURL: "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "ale", Name: "ale",
Version: "3.3.0", Version: "3.3.0",
@@ -27,72 +28,78 @@ func TestParsePubspecLock(t *testing.T) {
}, },
}, },
{ {
Name: "analyzer", Name: "analyzer",
Version: "0.40.7", Version: "0.40.7",
PURL: "pkg:pub/analyzer@0.40.7", PURL: "pkg:pub/analyzer@0.40.7",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "analyzer", Name: "analyzer",
Version: "0.40.7", Version: "0.40.7",
}, },
}, },
{ {
Name: "ansicolor", Name: "ansicolor",
Version: "1.1.1", Version: "1.1.1",
PURL: "pkg:pub/ansicolor@1.1.1", PURL: "pkg:pub/ansicolor@1.1.1",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "ansicolor", Name: "ansicolor",
Version: "1.1.1", Version: "1.1.1",
}, },
}, },
{ {
Name: "archive", Name: "archive",
Version: "2.0.13", Version: "2.0.13",
PURL: "pkg:pub/archive@2.0.13", PURL: "pkg:pub/archive@2.0.13",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "archive", Name: "archive",
Version: "2.0.13", Version: "2.0.13",
}, },
}, },
{ {
Name: "args", Name: "args",
Version: "1.6.0", Version: "1.6.0",
PURL: "pkg:pub/args@1.6.0", PURL: "pkg:pub/args@1.6.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "args", Name: "args",
Version: "1.6.0", Version: "1.6.0",
}, },
}, },
{ {
Name: "flutter", Name: "flutter",
Version: "0.0.0", Version: "0.0.0",
PURL: "pkg:pub/flutter@0.0.0", PURL: "pkg:pub/flutter@0.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "flutter", Name: "flutter",
Version: "0.0.0", Version: "0.0.0",
}, },
}, },
{ {
Name: "key_binder", Name: "key_binder",
Version: "1.11.20", Version: "1.11.20",
PURL: "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com:Workiva/key_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7", PURL: "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com:Workiva/key_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dart, Language: pkg.Dart,
Type: pkg.DartPubPkg, Type: pkg.DartPubPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DartPubspecLockEntry{ Metadata: pkg.DartPubspecLockEntry{
Name: "key_binder", Name: "key_binder",
Version: "1.11.20", Version: "1.11.20",
+4 -2
View File
@@ -36,7 +36,8 @@ func TestDpkgCataloger(t *testing.T) {
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.conffiles"), file.NewLocation("/var/lib/dpkg/info/libpam-runtime.conffiles"),
file.NewLocation("/usr/share/doc/libpam-runtime/copyright"), file.NewLocation("/usr/share/doc/libpam-runtime/copyright"),
), ),
Type: pkg.DebPkg, Type: pkg.DebPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DpkgDBEntry{ Metadata: pkg.DpkgDBEntry{
Package: "libpam-runtime", Package: "libpam-runtime",
Source: "pam", Source: "pam",
@@ -109,7 +110,8 @@ func TestDpkgCataloger(t *testing.T) {
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.preinst"), file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.preinst"),
file.NewLocation("/usr/share/doc/libsqlite3-0/copyright"), file.NewLocation("/usr/share/doc/libsqlite3-0/copyright"),
), ),
Type: pkg.DebPkg, Type: pkg.DebPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DpkgDBEntry{ Metadata: pkg.DpkgDBEntry{
Package: "libsqlite3-0", Package: "libsqlite3-0",
Source: "sqlite3", Source: "sqlite3",
+8 -7
View File
@@ -30,13 +30,14 @@ func newDpkgPackage(d pkg.DpkgDBEntry, dbLocation file.Location, resolver file.R
locations.Add(evidence...) locations.Add(evidence...)
p := pkg.Package{ p := pkg.Package{
Name: d.Package, Name: d.Package,
Version: d.Version, Version: d.Version,
Licenses: pkg.NewLicenseSet(licenses...), Licenses: pkg.NewLicenseSet(licenses...),
Locations: locations, Locations: locations,
PURL: packageURL(d, release), PURL: packageURL(d, release),
Type: pkg.DebPkg, Type: pkg.DebPkg,
Metadata: d, Dependencies: pkg.CompleteDependencies,
Metadata: d,
} }
if resolver != nil { if resolver != nil {
@@ -349,11 +349,12 @@ Installed-Size: 10kib
`, `,
want: []pkg.Package{ want: []pkg.Package{
{ {
Name: "apt", Name: "apt",
Type: "deb", Type: "deb",
PURL: "pkg:deb/debian/apt?distro=debian-10", PURL: "pkg:deb/debian/apt?distro=debian-10",
Licenses: pkg.NewLicenseSet(), Licenses: pkg.NewLicenseSet(),
Locations: file.NewLocationSet(file.NewLocation("place")), Locations: file.NewLocationSet(file.NewLocation("place")),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DpkgDBEntry{ Metadata: pkg.DpkgDBEntry{
Package: "apt", Package: "apt",
InstalledSize: 10240, InstalledSize: 10240,
+8 -7
View File
@@ -22,13 +22,14 @@ func newDotnetDepsPackage(nameVersion string, lib dotnetDepsLibrary, locations .
} }
p := &pkg.Package{ p := &pkg.Package{
Name: name, Name: name,
Version: version, Version: version,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(m), PURL: packageURL(m),
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Metadata: m, Dependencies: pkg.CompleteDependencies,
Metadata: m,
} }
p.SetID() p.SetID()
@@ -20,36 +20,39 @@ func TestParseDotnetDeps(t *testing.T) {
fixture := "test-fixtures/TestLibrary.deps.json" fixture := "test-fixtures/TestLibrary.deps.json"
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture)) fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
rootPkg := pkg.Package{ rootPkg := pkg.Package{
Name: "TestLibrary", Name: "TestLibrary",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:nuget/TestLibrary@1.0.0", PURL: "pkg:nuget/TestLibrary@1.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "TestLibrary", Name: "TestLibrary",
Version: "1.0.0", Version: "1.0.0",
}, },
} }
testCommon := pkg.Package{ testCommon := pkg.Package{
Name: "TestCommon", Name: "TestCommon",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:nuget/TestCommon@1.0.0", PURL: "pkg:nuget/TestCommon@1.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "TestCommon", Name: "TestCommon",
Version: "1.0.0", Version: "1.0.0",
}, },
} }
awssdkcore := pkg.Package{ awssdkcore := pkg.Package{
Name: "AWSSDK.Core", Name: "AWSSDK.Core",
Version: "3.7.10.6", Version: "3.7.10.6",
PURL: "pkg:nuget/AWSSDK.Core@3.7.10.6", PURL: "pkg:nuget/AWSSDK.Core@3.7.10.6",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "AWSSDK.Core", Name: "AWSSDK.Core",
Version: "3.7.10.6", Version: "3.7.10.6",
@@ -59,12 +62,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftDependencyInjectionAbstractions := pkg.Package{ msftDependencyInjectionAbstractions := pkg.Package{
Name: "Microsoft.Extensions.DependencyInjection.Abstractions", Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.DependencyInjection.Abstractions", Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
Version: "6.0.0", Version: "6.0.0",
@@ -74,12 +78,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftDependencyInjection := pkg.Package{ msftDependencyInjection := pkg.Package{
Name: "Microsoft.Extensions.DependencyInjection", Name: "Microsoft.Extensions.DependencyInjection",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.DependencyInjection", Name: "Microsoft.Extensions.DependencyInjection",
Version: "6.0.0", Version: "6.0.0",
@@ -89,12 +94,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftLoggingAbstractions := pkg.Package{ msftLoggingAbstractions := pkg.Package{
Name: "Microsoft.Extensions.Logging.Abstractions", Name: "Microsoft.Extensions.Logging.Abstractions",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.Logging.Abstractions", Name: "Microsoft.Extensions.Logging.Abstractions",
Version: "6.0.0", Version: "6.0.0",
@@ -104,12 +110,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftExtensionsLogging := pkg.Package{ msftExtensionsLogging := pkg.Package{
Name: "Microsoft.Extensions.Logging", Name: "Microsoft.Extensions.Logging",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.Logging@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.Logging@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.Logging", Name: "Microsoft.Extensions.Logging",
Version: "6.0.0", Version: "6.0.0",
@@ -119,12 +126,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftExtensionsOptions := pkg.Package{ msftExtensionsOptions := pkg.Package{
Name: "Microsoft.Extensions.Options", Name: "Microsoft.Extensions.Options",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.Options@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.Options@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.Options", Name: "Microsoft.Extensions.Options",
Version: "6.0.0", Version: "6.0.0",
@@ -134,12 +142,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
msftExtensionsPrimitives := pkg.Package{ msftExtensionsPrimitives := pkg.Package{
Name: "Microsoft.Extensions.Primitives", Name: "Microsoft.Extensions.Primitives",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/Microsoft.Extensions.Primitives@6.0.0", PURL: "pkg:nuget/Microsoft.Extensions.Primitives@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Microsoft.Extensions.Primitives", Name: "Microsoft.Extensions.Primitives",
Version: "6.0.0", Version: "6.0.0",
@@ -149,12 +158,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
newtonsoftJson := pkg.Package{ newtonsoftJson := pkg.Package{
Name: "Newtonsoft.Json", Name: "Newtonsoft.Json",
Version: "13.0.1", Version: "13.0.1",
PURL: "pkg:nuget/Newtonsoft.Json@13.0.1", PURL: "pkg:nuget/Newtonsoft.Json@13.0.1",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Newtonsoft.Json", Name: "Newtonsoft.Json",
Version: "13.0.1", Version: "13.0.1",
@@ -164,12 +174,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
serilogSinksConsole := pkg.Package{ serilogSinksConsole := pkg.Package{
Name: "Serilog.Sinks.Console", Name: "Serilog.Sinks.Console",
Version: "4.0.1", Version: "4.0.1",
PURL: "pkg:nuget/Serilog.Sinks.Console@4.0.1", PURL: "pkg:nuget/Serilog.Sinks.Console@4.0.1",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Serilog.Sinks.Console", Name: "Serilog.Sinks.Console",
Version: "4.0.1", Version: "4.0.1",
@@ -179,12 +190,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
serilog := pkg.Package{ serilog := pkg.Package{
Name: "Serilog", Name: "Serilog",
Version: "2.10.0", Version: "2.10.0",
PURL: "pkg:nuget/Serilog@2.10.0", PURL: "pkg:nuget/Serilog@2.10.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "Serilog", Name: "Serilog",
Version: "2.10.0", Version: "2.10.0",
@@ -194,12 +206,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
systemDiagnosticsDiagnosticsource := pkg.Package{ systemDiagnosticsDiagnosticsource := pkg.Package{
Name: "System.Diagnostics.DiagnosticSource", Name: "System.Diagnostics.DiagnosticSource",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/System.Diagnostics.DiagnosticSource@6.0.0", PURL: "pkg:nuget/System.Diagnostics.DiagnosticSource@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "System.Diagnostics.DiagnosticSource", Name: "System.Diagnostics.DiagnosticSource",
Version: "6.0.0", Version: "6.0.0",
@@ -209,12 +222,13 @@ func TestParseDotnetDeps(t *testing.T) {
}, },
} }
systemRuntimeCompilerServicesUnsafe := pkg.Package{ systemRuntimeCompilerServicesUnsafe := pkg.Package{
Name: "System.Runtime.CompilerServices.Unsafe", Name: "System.Runtime.CompilerServices.Unsafe",
Version: "6.0.0", Version: "6.0.0",
PURL: "pkg:nuget/System.Runtime.CompilerServices.Unsafe@6.0.0", PURL: "pkg:nuget/System.Runtime.CompilerServices.Unsafe@6.0.0",
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
Language: pkg.Dotnet, Language: pkg.Dotnet,
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.DotnetDepsEntry{ Metadata: pkg.DotnetDepsEntry{
Name: "System.Runtime.CompilerServices.Unsafe", Name: "System.Runtime.CompilerServices.Unsafe",
Version: "6.0.0", Version: "6.0.0",
@@ -9,7 +9,7 @@ import (
"github.com/saferwall/pe" "github.com/saferwall/pe"
version "github.com/anchore/go-version" "github.com/anchore/go-version"
"github.com/anchore/packageurl-go" "github.com/anchore/packageurl-go"
"github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/artifact"
@@ -44,7 +44,7 @@ func parseDotnetPortableExecutable(_ context.Context, _ file.Resolver, _ *generi
return nil, nil, fmt.Errorf("unable to parse version resources in PE file: %w", err) return nil, nil, fmt.Errorf("unable to parse version resources in PE file: %w", err)
} }
dotNetPkg, err := buildDotNetPackage(versionResources, f) dotNetPkg, err := buildDotNetPEPackage(versionResources, f)
if err != nil { if err != nil {
log.Tracef("unable to build dotnet package for: %v %v", f.RealPath, err) log.Tracef("unable to build dotnet package for: %v %v", f.RealPath, err)
return nil, nil, err return nil, nil, err
@@ -53,14 +53,14 @@ func parseDotnetPortableExecutable(_ context.Context, _ file.Resolver, _ *generi
return []pkg.Package{dotNetPkg}, nil, nil return []pkg.Package{dotNetPkg}, nil, nil
} }
func buildDotNetPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) { func buildDotNetPEPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) {
name := findName(versionResources) name := findName(versionResources)
if name == "" { if name == "" {
return dnpkg, fmt.Errorf("unable to find PE name in file") return dnpkg, fmt.Errorf("unable to find PE name in file")
} }
version := findVersion(versionResources) ver := findVersion(versionResources)
if version == "" { if ver == "" {
return dnpkg, fmt.Errorf("unable to find PE version in file") return dnpkg, fmt.Errorf("unable to find PE version in file")
} }
@@ -76,12 +76,14 @@ func buildDotNetPackage(versionResources map[string]string, f file.LocationReadC
dnpkg = pkg.Package{ dnpkg = pkg.Package{
Name: name, Name: name,
Version: version, Version: ver,
Locations: file.NewLocationSet(f.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(f.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
Type: pkg.DotnetPkg, Type: pkg.DotnetPkg,
Language: pkg.Dotnet, Language: pkg.Dotnet,
PURL: portableExecutablePackageURL(name, version), PURL: portableExecutablePackageURL(name, ver),
Metadata: metadata, // by nature PE file metadata does not have any dependency information, thus we are forced to claim unknown completeness
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: metadata,
} }
dnpkg.SetID() dnpkg.SetID()
@@ -32,8 +32,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"Assembly Version": "3.14.2.11", "Assembly Version": "3.14.2.11",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Active Directory Authentication Library", Name: "Active Directory Authentication Library",
Version: "3.14.40721.0918", Version: "3.14.40721.0918",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DotnetPortableExecutableEntry{ Metadata: pkg.DotnetPortableExecutableEntry{
AssemblyVersion: "3.14.2.11", AssemblyVersion: "3.14.2.11",
LegalCopyright: "Copyright (c) Microsoft Corporation. All rights reserved.", LegalCopyright: "Copyright (c) Microsoft Corporation. All rights reserved.",
@@ -57,9 +58,10 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "4.6.25512.01 built by: dlab-DDVSOWINAGE016. Commit Hash: d0d5c7b49271cadb6d97de26d8e623e98abdc8db", "ProductVersion": "4.6.25512.01 built by: dlab-DDVSOWINAGE016. Commit Hash: d0d5c7b49271cadb6d97de26d8e623e98abdc8db",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "äbFileVersi on", Name: "äbFileVersi on",
Version: "4.6.25512.01", Version: "4.6.25512.01",
PURL: "pkg:nuget/%C3%A4bFileVersi%20on@4.6.25512.01", PURL: "pkg:nuget/%C3%A4bFileVersi%20on@4.6.25512.01",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.DotnetPortableExecutableEntry{ Metadata: pkg.DotnetPortableExecutableEntry{
LegalCopyright: "© Microsoft Corporation. All rights reserved.", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
InternalName: "äb\x01FileVersion", InternalName: "äb\x01FileVersion",
@@ -82,8 +84,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "4.7.3190.0", "ProductVersion": "4.7.3190.0",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "System.Data.Linq.dll", Name: "System.Data.Linq.dll",
Version: "4.7.3190.0", Version: "4.7.3190.0",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -99,8 +102,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "8.4.0", "ProductVersion": "8.4.0",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "The curl executable", Name: "The curl executable",
Version: "8.4.0", Version: "8.4.0",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -116,8 +120,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "8.0.1", "ProductVersion": "8.0.1",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Prometheus.AspNetCore.dll", Name: "Prometheus.AspNetCore.dll",
Version: "8.0.1", Version: "8.0.1",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -132,8 +137,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "1, 0, 0, 0", "ProductVersion": "1, 0, 0, 0",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Hidden Input", Name: "Hidden Input",
Version: "1, 0, 0, 0", Version: "1, 0, 0, 0",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -148,8 +154,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.23.2", "ProductVersion": "3.23.2",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "SQLite", Name: "SQLite",
Version: "3.23.2", Version: "3.23.2",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -165,8 +172,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "80.1.7.92", "ProductVersion": "80.1.7.92",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Brave Browser", Name: "Brave Browser",
Version: "80.1.7.92", Version: "80.1.7.92",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -177,8 +185,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "80.1.7.92", "ProductVersion": "80.1.7.92",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Better version", Name: "Better version",
Version: "80.1.7.92", Version: "80.1.7.92",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -189,8 +198,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "80.1.7", "ProductVersion": "80.1.7",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Better version", Name: "Better version",
Version: "80.1.7.92", Version: "80.1.7.92",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -201,8 +211,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", "ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Higher semantic version Product Version", Name: "Higher semantic version Product Version",
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -213,8 +224,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.0.0", "ProductVersion": "3.0.0",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Higher semantic version File Version", Name: "Higher semantic version File Version",
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -225,8 +237,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", "ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Invalid semantic version File Version", Name: "Invalid semantic version File Version",
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -237,8 +250,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", "ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Invalid semantic version File Version", Name: "Invalid semantic version File Version",
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -249,8 +263,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "A", "ProductVersion": "A",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Invalid semantic version Product Version", Name: "Invalid semantic version Product Version",
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207", Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
{ {
@@ -261,8 +276,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
"ProductVersion": "3.0.0", "ProductVersion": "3.0.0",
}, },
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "Semantically equal falls through, chooses File Version with more components", Name: "Semantically equal falls through, chooses File Version with more components",
Version: "3.0.0.0", Version: "3.0.0.0",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
} }
@@ -273,7 +289,7 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
f := file.LocationReadCloser{ f := file.LocationReadCloser{
Location: location, Location: location,
} }
got, err := buildDotNetPackage(tc.versionResources, f) got, err := buildDotNetPEPackage(tc.versionResources, f)
assert.NoErrorf(t, err, "failed to build package from version resources: %+v", tc.versionResources) assert.NoErrorf(t, err, "failed to build package from version resources: %+v", tc.versionResources)
// ignore certain metadata // ignore certain metadata
+3 -1
View File
@@ -14,7 +14,9 @@ func newPackage(d pkg.ElixirMixLockEntry, locations ...file.Location) pkg.Packag
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(d), PURL: packageURL(d),
Type: pkg.HexPkg, Type: pkg.HexPkg,
Metadata: d, // we do not attempt to parse dependencies from the mix.lock file
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: d,
} }
p.SetID() p.SetID()
+105 -90
View File
@@ -13,12 +13,13 @@ func TestParseMixLock(t *testing.T) {
locations := file.NewLocationSet(file.NewLocation("test-fixtures/mix.lock")) locations := file.NewLocationSet(file.NewLocation("test-fixtures/mix.lock"))
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "castore", Name: "castore",
Version: "0.1.17", Version: "0.1.17",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/castore@0.1.17", PURL: "pkg:hex/castore@0.1.17",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "castore", Name: "castore",
Version: "0.1.17", Version: "0.1.17",
@@ -27,12 +28,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "connection", Name: "connection",
Version: "1.1.0", Version: "1.1.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/connection@1.1.0", PURL: "pkg:hex/connection@1.1.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "connection", Name: "connection",
Version: "1.1.0", Version: "1.1.0",
@@ -41,12 +43,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "cowboy", Name: "cowboy",
Version: "2.9.0", Version: "2.9.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/cowboy@2.9.0", PURL: "pkg:hex/cowboy@2.9.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "cowboy", Name: "cowboy",
Version: "2.9.0", Version: "2.9.0",
@@ -55,12 +58,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "cowboy_telemetry", Name: "cowboy_telemetry",
Version: "0.4.0", Version: "0.4.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/cowboy_telemetry@0.4.0", PURL: "pkg:hex/cowboy_telemetry@0.4.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "cowboy_telemetry", Name: "cowboy_telemetry",
Version: "0.4.0", Version: "0.4.0",
@@ -69,12 +73,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "cowlib", Name: "cowlib",
Version: "2.11.0", Version: "2.11.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/cowlib@2.11.0", PURL: "pkg:hex/cowlib@2.11.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "cowlib", Name: "cowlib",
Version: "2.11.0", Version: "2.11.0",
@@ -83,12 +88,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "db_connection", Name: "db_connection",
Version: "2.4.2", Version: "2.4.2",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/db_connection@2.4.2", PURL: "pkg:hex/db_connection@2.4.2",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "db_connection", Name: "db_connection",
Version: "2.4.2", Version: "2.4.2",
@@ -97,12 +103,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "decimal", Name: "decimal",
Version: "2.0.0", Version: "2.0.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/decimal@2.0.0", PURL: "pkg:hex/decimal@2.0.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "decimal", Name: "decimal",
Version: "2.0.0", Version: "2.0.0",
@@ -111,12 +118,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "earmark_parser", Name: "earmark_parser",
Version: "1.4.25", Version: "1.4.25",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/earmark_parser@1.4.25", PURL: "pkg:hex/earmark_parser@1.4.25",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "earmark_parser", Name: "earmark_parser",
Version: "1.4.25", Version: "1.4.25",
@@ -125,12 +133,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "ecto", Name: "ecto",
Version: "3.8.1", Version: "3.8.1",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/ecto@3.8.1", PURL: "pkg:hex/ecto@3.8.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "ecto", Name: "ecto",
Version: "3.8.1", Version: "3.8.1",
@@ -139,12 +148,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "ecto_sql", Name: "ecto_sql",
Version: "3.8.1", Version: "3.8.1",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/ecto_sql@3.8.1", PURL: "pkg:hex/ecto_sql@3.8.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "ecto_sql", Name: "ecto_sql",
Version: "3.8.1", Version: "3.8.1",
@@ -153,12 +163,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "esbuild", Name: "esbuild",
Version: "0.5.0", Version: "0.5.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/esbuild@0.5.0", PURL: "pkg:hex/esbuild@0.5.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "esbuild", Name: "esbuild",
Version: "0.5.0", Version: "0.5.0",
@@ -167,12 +178,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "ex_doc", Name: "ex_doc",
Version: "0.28.4", Version: "0.28.4",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/ex_doc@0.28.4", PURL: "pkg:hex/ex_doc@0.28.4",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "ex_doc", Name: "ex_doc",
Version: "0.28.4", Version: "0.28.4",
@@ -181,12 +193,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "gettext", Name: "gettext",
Version: "0.19.1", Version: "0.19.1",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/gettext@0.19.1", PURL: "pkg:hex/gettext@0.19.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "gettext", Name: "gettext",
Version: "0.19.1", Version: "0.19.1",
@@ -195,12 +208,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "hpax", Name: "hpax",
Version: "0.1.1", Version: "0.1.1",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/hpax@0.1.1", PURL: "pkg:hex/hpax@0.1.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "hpax", Name: "hpax",
Version: "0.1.1", Version: "0.1.1",
@@ -209,12 +223,13 @@ func TestParseMixLock(t *testing.T) {
}, },
}, },
{ {
Name: "jason", Name: "jason",
Version: "1.3.0", Version: "1.3.0",
Language: pkg.Elixir, Language: pkg.Elixir,
Type: pkg.HexPkg, Type: pkg.HexPkg,
Locations: locations, Locations: locations,
PURL: "pkg:hex/jason@1.3.0", PURL: "pkg:hex/jason@1.3.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ElixirMixLockEntry{ Metadata: pkg.ElixirMixLockEntry{
Name: "jason", Name: "jason",
Version: "1.3.0", Version: "1.3.0",
+6 -2
View File
@@ -14,7 +14,9 @@ func newPackageFromRebar(d pkg.ErlangRebarLockEntry, locations ...file.Location)
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURLFromRebar(d), PURL: packageURLFromRebar(d),
Type: pkg.HexPkg, Type: pkg.HexPkg,
Metadata: d, // we do not attempt to parse dependencies from the rebar.lock file
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: d,
} }
p.SetID() p.SetID()
@@ -42,7 +44,9 @@ func newPackageFromOTP(name, version string, locations ...file.Location) pkg.Pac
Language: pkg.Erlang, Language: pkg.Erlang,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURLFromOTP(name, version), PURL: packageURLFromOTP(name, version),
Type: pkg.ErlangOTPPkg, // we do not attempt to parse dependencies from app files
Dependencies: pkg.UnknownDependencyCompleteness,
Type: pkg.ErlangOTPPkg,
} }
p.SetID() p.SetID()
@@ -18,11 +18,12 @@ func TestParseOTPApplication(t *testing.T) {
fixture: "test-fixtures/rabbitmq.app", fixture: "test-fixtures/rabbitmq.app",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "rabbit", Name: "rabbit",
Version: "3.12.10", Version: "3.12.10",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.ErlangOTPPkg, Type: pkg.ErlangOTPPkg,
PURL: "pkg:otp/rabbit@3.12.10", PURL: "pkg:otp/rabbit@3.12.10",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
}, },
@@ -18,11 +18,12 @@ func TestParseRebarLock(t *testing.T) {
fixture: "test-fixtures/rebar.lock", fixture: "test-fixtures/rebar.lock",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "certifi", Name: "certifi",
Version: "2.9.0", Version: "2.9.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/certifi@2.9.0", PURL: "pkg:hex/certifi@2.9.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "certifi", Name: "certifi",
Version: "2.9.0", Version: "2.9.0",
@@ -31,11 +32,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "idna", Name: "idna",
Version: "6.1.1", Version: "6.1.1",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/idna@6.1.1", PURL: "pkg:hex/idna@6.1.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "idna", Name: "idna",
Version: "6.1.1", Version: "6.1.1",
@@ -44,11 +46,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "metrics", Name: "metrics",
Version: "1.0.1", Version: "1.0.1",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/metrics@1.0.1", PURL: "pkg:hex/metrics@1.0.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "metrics", Name: "metrics",
Version: "1.0.1", Version: "1.0.1",
@@ -57,11 +60,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "mimerl", Name: "mimerl",
Version: "1.2.0", Version: "1.2.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/mimerl@1.2.0", PURL: "pkg:hex/mimerl@1.2.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "mimerl", Name: "mimerl",
Version: "1.2.0", Version: "1.2.0",
@@ -70,11 +74,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "parse_trans", Name: "parse_trans",
Version: "3.3.1", Version: "3.3.1",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/parse_trans@3.3.1", PURL: "pkg:hex/parse_trans@3.3.1",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "parse_trans", Name: "parse_trans",
Version: "3.3.1", Version: "3.3.1",
@@ -83,11 +88,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "ssl_verify_fun", Name: "ssl_verify_fun",
Version: "1.1.6", Version: "1.1.6",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/ssl_verify_fun@1.1.6", PURL: "pkg:hex/ssl_verify_fun@1.1.6",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "ssl_verify_fun", Name: "ssl_verify_fun",
Version: "1.1.6", Version: "1.1.6",
@@ -96,11 +102,12 @@ func TestParseRebarLock(t *testing.T) {
}, },
}, },
{ {
Name: "unicode_util_compat", Name: "unicode_util_compat",
Version: "0.7.0", Version: "0.7.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/unicode_util_compat@0.7.0", PURL: "pkg:hex/unicode_util_compat@0.7.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "unicode_util_compat", Name: "unicode_util_compat",
Version: "0.7.0", Version: "0.7.0",
@@ -117,11 +124,12 @@ func TestParseRebarLock(t *testing.T) {
// {<<"bcrypt">>, <<"A6763BD4E1AF46D34776F85B7995E63A02978DE110C077E9570ED17006E03386">>}, // {<<"bcrypt">>, <<"A6763BD4E1AF46D34776F85B7995E63A02978DE110C077E9570ED17006E03386">>},
// {<<"bcrypt">>, <<"3418821BC17CE6E96A4A77D1A88D7485BF783E212069FACFC79510AFBFF95352">>}, // {<<"bcrypt">>, <<"3418821BC17CE6E96A4A77D1A88D7485BF783E212069FACFC79510AFBFF95352">>},
{ {
Name: "bcrypt", Name: "bcrypt",
Version: "1.1.5", Version: "1.1.5",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/bcrypt@1.1.5", PURL: "pkg:hex/bcrypt@1.1.5",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "bcrypt", Name: "bcrypt",
Version: "1.1.5", Version: "1.1.5",
@@ -134,11 +142,12 @@ func TestParseRebarLock(t *testing.T) {
// {ref,"14308ab927cfa69324742c3de720578094e0bb19"}}, // {ref,"14308ab927cfa69324742c3de720578094e0bb19"}},
// 1}, // 1},
{ {
Name: "bson", Name: "bson",
Version: "14308ab927cfa69324742c3de720578094e0bb19", Version: "14308ab927cfa69324742c3de720578094e0bb19",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/bson@14308ab927cfa69324742c3de720578094e0bb19", PURL: "pkg:hex/bson@14308ab927cfa69324742c3de720578094e0bb19",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "bson", Name: "bson",
Version: "14308ab927cfa69324742c3de720578094e0bb19", Version: "14308ab927cfa69324742c3de720578094e0bb19",
@@ -148,11 +157,12 @@ func TestParseRebarLock(t *testing.T) {
// {<<"certifi">>, <<"6F2A475689DD47F19FB74334859D460A2DC4E3252A3324BD2111B8F0429E7E21">>}, {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>}, // {<<"certifi">>, <<"6F2A475689DD47F19FB74334859D460A2DC4E3252A3324BD2111B8F0429E7E21">>}, {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>},
// {<<"certifi">>, <<"266DA46BDB06D6C6D35FDE799BCB28D36D985D424AD7C08B5BB48F5B5CDD4641">>}, // {<<"certifi">>, <<"266DA46BDB06D6C6D35FDE799BCB28D36D985D424AD7C08B5BB48F5B5CDD4641">>},
{ {
Name: "certifi", Name: "certifi",
Version: "2.9.0", Version: "2.9.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/certifi@2.9.0", PURL: "pkg:hex/certifi@2.9.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "certifi", Name: "certifi",
Version: "2.9.0", Version: "2.9.0",
@@ -164,11 +174,12 @@ func TestParseRebarLock(t *testing.T) {
// {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>}, // {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>},
// {<<"stdout_formatter">>, <<"6B9CAAD8930006F9BB35680C5D3311917AC67690C3AF1BA018623324C015ABE5">>}, // {<<"stdout_formatter">>, <<"6B9CAAD8930006F9BB35680C5D3311917AC67690C3AF1BA018623324C015ABE5">>},
{ {
Name: "stdout_formatter", Name: "stdout_formatter",
Version: "0.2.3", Version: "0.2.3",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/stdout_formatter@0.2.3", PURL: "pkg:hex/stdout_formatter@0.2.3",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "stdout_formatter", Name: "stdout_formatter",
Version: "0.2.3", Version: "0.2.3",
@@ -181,11 +192,12 @@ func TestParseRebarLock(t *testing.T) {
// {ref,"4835239dca5a5f4ac7202dd94d7effcaa617d575"}}, // {ref,"4835239dca5a5f4ac7202dd94d7effcaa617d575"}},
// 0}, // 0},
{ {
Name: "swc", Name: "swc",
Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575", Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/swc@4835239dca5a5f4ac7202dd94d7effcaa617d575", PURL: "pkg:hex/swc@4835239dca5a5f4ac7202dd94d7effcaa617d575",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "swc", Name: "swc",
Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575", Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575",
@@ -195,11 +207,12 @@ func TestParseRebarLock(t *testing.T) {
// {<<"syslog">>, <<"6419A232BEA84F07B56DC575225007FFE34D9FDC91ABE6F1B2F254FD71D8EFC2">>}, // {<<"syslog">>, <<"6419A232BEA84F07B56DC575225007FFE34D9FDC91ABE6F1B2F254FD71D8EFC2">>},
// {<<"syslog">>, <<"4C6A41373C7E20587BE33EF841D3DE6F3BEBA08519809329ECC4D27B15B659E1">>}, // {<<"syslog">>, <<"4C6A41373C7E20587BE33EF841D3DE6F3BEBA08519809329ECC4D27B15B659E1">>},
{ {
Name: "syslog", Name: "syslog",
Version: "1.1.0", Version: "1.1.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/syslog@1.1.0", PURL: "pkg:hex/syslog@1.1.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "syslog", Name: "syslog",
Version: "1.1.0", Version: "1.1.0",
@@ -211,11 +224,12 @@ func TestParseRebarLock(t *testing.T) {
// {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]}, // {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
// {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} // {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
{ {
Name: "unicode_util_compat", Name: "unicode_util_compat",
Version: "0.7.0", Version: "0.7.0",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/unicode_util_compat@0.7.0", PURL: "pkg:hex/unicode_util_compat@0.7.0",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "unicode_util_compat", Name: "unicode_util_compat",
Version: "0.7.0", Version: "0.7.0",
@@ -228,11 +242,12 @@ func TestParseRebarLock(t *testing.T) {
// {ref,"6d622aa8c901ae7777433aef2bd049e380c474a6"}}, // {ref,"6d622aa8c901ae7777433aef2bd049e380c474a6"}},
// 0}]}. // 0}]}.
{ {
Name: "vernemq_dev", Name: "vernemq_dev",
Version: "6d622aa8c901ae7777433aef2bd049e380c474a6", Version: "6d622aa8c901ae7777433aef2bd049e380c474a6",
Language: pkg.Erlang, Language: pkg.Erlang,
Type: pkg.HexPkg, Type: pkg.HexPkg,
PURL: "pkg:hex/vernemq_dev@6d622aa8c901ae7777433aef2bd049e380c474a6", PURL: "pkg:hex/vernemq_dev@6d622aa8c901ae7777433aef2bd049e380c474a6",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.ErlangRebarLockEntry{ Metadata: pkg.ErlangRebarLockEntry{
Name: "vernemq_dev", Name: "vernemq_dev",
Version: "6d622aa8c901ae7777433aef2bd049e380c474a6", Version: "6d622aa8c901ae7777433aef2bd049e380c474a6",
+3 -2
View File
@@ -22,8 +22,9 @@ func TestPortageCataloger(t *testing.T) {
file.NewLocation("var/db/pkg/app-containers/skopeo-1.5.1/SIZE"), file.NewLocation("var/db/pkg/app-containers/skopeo-1.5.1/SIZE"),
expectedLicenseLocation, expectedLicenseLocation,
), ),
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(expectedLicenseLocation, "Apache-2.0", "BSD", "BSD-2", "CC-BY-SA-4.0", "ISC", "MIT")...), Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(expectedLicenseLocation, "Apache-2.0", "BSD", "BSD-2", "CC-BY-SA-4.0", "ISC", "MIT")...),
Type: pkg.PortagePkg, Type: pkg.PortagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PortageEntry{ Metadata: pkg.PortageEntry{
InstalledSize: 27937835, InstalledSize: 27937835,
Files: []pkg.PortageFileRecord{ Files: []pkg.PortageFileRecord{
@@ -45,7 +45,8 @@ func parsePortageContents(_ context.Context, resolver file.Resolver, _ *generic.
Locations: file.NewLocationSet( Locations: file.NewLocationSet(
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Type: pkg.PortagePkg, Dependencies: pkg.UnknownDependencyCompleteness,
Type: pkg.PortagePkg,
Metadata: pkg.PortageEntry{ Metadata: pkg.PortageEntry{
// ensure the default value for a collection is never nil since this may be shown as JSON // ensure the default value for a collection is never nil since this may be shown as JSON
Files: make([]pkg.PortageFileRecord, 0), Files: make([]pkg.PortageFileRecord, 0),
+6 -2
View File
@@ -31,7 +31,9 @@ func newGithubActionWorkflowPackageUsage(name, version string, workflowLocation
Version: version, Version: version,
Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
PURL: packageURL(name, version), PURL: packageURL(name, version),
Type: pkg.GithubActionWorkflowPkg, // we have full visibility into the dependencies of a workflow file except for when using shared workflows
Dependencies: pkg.CompleteDependencies,
Type: pkg.GithubActionWorkflowPkg,
} }
p.SetID() p.SetID()
@@ -45,7 +47,9 @@ func newGithubActionPackageUsage(name, version string, workflowLocation file.Loc
Version: version, Version: version,
Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
PURL: packageURL(name, version), PURL: packageURL(name, version),
Type: pkg.GithubActionPkg, // we cannot see what the dependencies are for a github action are locally from workflow yaml files
Dependencies: pkg.UnknownDependencyCompleteness,
Type: pkg.GithubActionPkg,
} }
p.SetID() p.SetID()
@@ -15,18 +15,20 @@ func Test_parseCompositeActionForActionUsage(t *testing.T) {
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "actions/setup-go", Name: "actions/setup-go",
Version: "v4", Version: "v4",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/setup-go@v4", PURL: "pkg:github/actions/setup-go@v4",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "actions/cache", Name: "actions/cache",
Version: "v3", Version: "v3",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/cache@v3", PURL: "pkg:github/actions/cache@v3",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
} }
@@ -15,39 +15,44 @@ func Test_parseWorkflowForActionUsage(t *testing.T) {
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "./.github/actions/bootstrap", Name: "./.github/actions/bootstrap",
Version: "", Version: "",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "actions/cache", Name: "actions/cache",
Version: "v3", Version: "v3",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/cache@v3", PURL: "pkg:github/actions/cache@v3",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "actions/cache/restore", Name: "actions/cache/restore",
Version: "v3", Version: "v3",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/cache@v3#restore", PURL: "pkg:github/actions/cache@v3#restore",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "actions/cache/save", Name: "actions/cache/save",
Version: "v3", Version: "v3",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/cache@v3#save", PURL: "pkg:github/actions/cache@v3#save",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "actions/checkout", Name: "actions/checkout",
Version: "v4", Version: "v4",
Type: pkg.GithubActionPkg, Type: pkg.GithubActionPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/actions/checkout@v4", PURL: "pkg:github/actions/checkout@v4",
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
} }
@@ -61,25 +66,28 @@ func Test_parseWorkflowForWorkflowUsage(t *testing.T) {
expected := []pkg.Package{ expected := []pkg.Package{
{ {
Name: "octo-org/this-repo/.github/workflows/workflow-1.yml", Name: "octo-org/this-repo/.github/workflows/workflow-1.yml",
Version: "172239021f7ba04fe7327647b213799853a9eb89", Version: "172239021f7ba04fe7327647b213799853a9eb89",
Type: pkg.GithubActionWorkflowPkg, Type: pkg.GithubActionWorkflowPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/octo-org/this-repo@172239021f7ba04fe7327647b213799853a9eb89#.github/workflows/workflow-1.yml", PURL: "pkg:github/octo-org/this-repo@172239021f7ba04fe7327647b213799853a9eb89#.github/workflows/workflow-1.yml",
Dependencies: pkg.CompleteDependencies,
}, },
{ {
Name: "./.github/workflows/workflow-2.yml", Name: "./.github/workflows/workflow-2.yml",
Version: "", Version: "",
Type: pkg.GithubActionWorkflowPkg, Type: pkg.GithubActionWorkflowPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
Dependencies: pkg.CompleteDependencies,
}, },
{ {
Name: "octo-org/another-repo/.github/workflows/workflow.yml", Name: "octo-org/another-repo/.github/workflows/workflow.yml",
Version: "v1", Version: "v1",
Type: pkg.GithubActionWorkflowPkg, Type: pkg.GithubActionWorkflowPkg,
Locations: fixtureLocationSet, Locations: fixtureLocationSet,
PURL: "pkg:github/octo-org/another-repo@v1#.github/workflows/workflow.yml", PURL: "pkg:github/octo-org/another-repo@v1#.github/workflows/workflow.yml",
Dependencies: pkg.CompleteDependencies,
}, },
} }
+9 -8
View File
@@ -9,19 +9,20 @@ import (
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
) )
func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, locations ...file.Location) pkg.Package { func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, dependencies pkg.DependencyCompleteness, locations ...file.Location) pkg.Package {
if dep.Replace != nil { if dep.Replace != nil {
dep = dep.Replace dep = dep.Replace
} }
p := pkg.Package{ p := pkg.Package{
Name: dep.Path, Name: dep.Path,
Version: dep.Version, Version: dep.Version,
Licenses: pkg.NewLicenseSet(licenses...), Licenses: pkg.NewLicenseSet(licenses...),
PURL: packageURL(dep.Path, dep.Version), PURL: packageURL(dep.Path, dep.Version),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
Dependencies: dependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goVersion, GoCompiledVersion: goVersion,
H1Digest: dep.Sum, H1Digest: dep.Sum,
@@ -134,6 +134,10 @@ func (c *goBinaryCataloger) buildGoPkgInfo(ctx context.Context, licenseScanner l
mod.cryptoSettings, mod.cryptoSettings,
experiments, experiments,
lics, lics,
// the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect
// dependencies are related directly to the main module. This means that we don't have any way to discover
// the completeness of the dependency's dependencies, thus they are unknown.
pkg.UnknownDependencyCompleteness,
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
) )
if pkg.IsValid(&p) { if pkg.IsValid(&p) {
@@ -178,6 +182,11 @@ func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanne
mod.cryptoSettings, mod.cryptoSettings,
experiments, experiments,
lics, lics,
// the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect
// dependencies are related directly to the main module. Also, we don't have a way to express on a package or
// relationship the nature of "//indirect" markings on dependencies so though the dependencies are complete
// and separable with the raw data, the data in the SBOM is not separable.
pkg.CompleteWithIndirectDependencies,
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
) )
@@ -161,6 +161,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -208,7 +209,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Metadata: pkg.GolangBinaryBuildinfoEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{},
}, },
}, },
}, },
@@ -253,6 +255,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -291,6 +294,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -365,6 +369,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -432,6 +437,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -497,6 +503,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -554,6 +561,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -611,6 +619,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -669,6 +678,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -741,6 +751,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -762,6 +773,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -819,12 +831,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
H1Digest: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=", H1Digest: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
MainModule: "github.com/anchore/syft", MainModule: "github.com/anchore/syft",
}}, },
},
{ {
Name: "golang.org/x/term", Name: "golang.org/x/term",
Version: "v0.0.0-20210916214954-140adaaadfaf", Version: "v0.0.0-20210916214954-140adaaadfaf",
@@ -839,6 +853,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -882,6 +897,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: goCompiledVersion, GoCompiledVersion: goCompiledVersion,
Architecture: archDetails, Architecture: archDetails,
@@ -941,6 +957,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: "go1.22.2", GoCompiledVersion: "go1.22.2",
Architecture: archDetails, Architecture: archDetails,
@@ -993,6 +1010,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: "go1.22.2", GoCompiledVersion: "go1.22.2",
Architecture: archDetails, Architecture: archDetails,
@@ -1013,6 +1031,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
}, },
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
Dependencies: pkg.CompleteWithIndirectDependencies,
Metadata: pkg.GolangBinaryBuildinfoEntry{ Metadata: pkg.GolangBinaryBuildinfoEntry{
GoCompiledVersion: "go1.22.2", GoCompiledVersion: "go1.22.2",
BuildSettings: []pkg.KeyValue{ BuildSettings: []pkg.KeyValue{
@@ -66,6 +66,9 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
PURL: packageURL(m.Mod.Path, m.Mod.Version), PURL: packageURL(m.Mod.Path, m.Mod.Version),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
// we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies
// so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{ Metadata: pkg.GolangModuleEntry{
H1Digest: digests[fmt.Sprintf("%s %s", m.Mod.Path, m.Mod.Version)], H1Digest: digests[fmt.Sprintf("%s %s", m.Mod.Path, m.Mod.Version)],
}, },
@@ -91,6 +94,9 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
PURL: packageURL(m.New.Path, m.New.Version), PURL: packageURL(m.New.Path, m.New.Version),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
// we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies
// so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{ Metadata: pkg.GolangModuleEntry{
H1Digest: digests[fmt.Sprintf("%s %s", m.New.Path, m.New.Version)], H1Digest: digests[fmt.Sprintf("%s %s", m.New.Path, m.New.Version)],
}, },
+81 -71
View File
@@ -18,13 +18,14 @@ func TestParseGoMod(t *testing.T) {
fixture: "test-fixtures/one-package", fixture: "test-fixtures/one-package",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "github.com/bmatcuk/doublestar", Name: "github.com/bmatcuk/doublestar",
Version: "v1.3.1", Version: "v1.3.1",
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1", PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/one-package")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/one-package")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
}, },
}, },
@@ -33,58 +34,64 @@ func TestParseGoMod(t *testing.T) {
fixture: "test-fixtures/many-packages", fixture: "test-fixtures/many-packages",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "github.com/anchore/archiver/v3", Name: "github.com/anchore/archiver/v3",
Version: "v3.5.2", Version: "v3.5.2",
PURL: "pkg:golang/github.com/anchore/archiver@v3.5.2#v3", PURL: "pkg:golang/github.com/anchore/archiver@v3.5.2#v3",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/anchore/go-testutils", Name: "github.com/anchore/go-testutils",
Version: "v0.0.0-20200624184116-66aa578126db", Version: "v0.0.0-20200624184116-66aa578126db",
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db", PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/anchore/go-version", Name: "github.com/anchore/go-version",
Version: "v1.2.2-0.20200701162849-18adb9c92b9b", Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b", PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/anchore/stereoscope", Name: "github.com/anchore/stereoscope",
Version: "v0.0.0-20200706164556-7cf39d7f4639", Version: "v0.0.0-20200706164556-7cf39d7f4639",
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639", PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/bmatcuk/doublestar", Name: "github.com/bmatcuk/doublestar",
Version: "v8.8.8", Version: "v8.8.8",
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8", PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/go-test/deep", Name: "github.com/go-test/deep",
Version: "v1.0.6", Version: "v1.0.6",
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6", PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")), Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
}, },
}, },
@@ -111,35 +118,38 @@ func Test_GoSumHashes(t *testing.T) {
fixture: "test-fixtures/go-sum-hashes", fixture: "test-fixtures/go-sum-hashes",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "github.com/CycloneDX/cyclonedx-go", Name: "github.com/CycloneDX/cyclonedx-go",
Version: "v0.6.0", Version: "v0.6.0",
PURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.6.0", PURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.6.0",
Locations: file.NewLocationSet(file.NewLocation("go.mod")), Locations: file.NewLocationSet(file.NewLocation("go.mod")),
FoundBy: "go-module-file-cataloger", FoundBy: "go-module-file-cataloger",
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Metadata: pkg.GolangModuleEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{},
}, },
{ {
Name: "github.com/acarl005/stripansi", Name: "github.com/acarl005/stripansi",
Version: "v0.0.0-20180116102854-5a71ef0e047d", Version: "v0.0.0-20180116102854-5a71ef0e047d",
PURL: "pkg:golang/github.com/acarl005/stripansi@v0.0.0-20180116102854-5a71ef0e047d", PURL: "pkg:golang/github.com/acarl005/stripansi@v0.0.0-20180116102854-5a71ef0e047d",
Locations: file.NewLocationSet(file.NewLocation("go.mod")), Locations: file.NewLocationSet(file.NewLocation("go.mod")),
FoundBy: "go-module-file-cataloger", FoundBy: "go-module-file-cataloger",
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{ Metadata: pkg.GolangModuleEntry{
H1Digest: "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=", H1Digest: "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=",
}, },
}, },
{ {
Name: "github.com/mgutz/ansi", Name: "github.com/mgutz/ansi",
Version: "v0.0.0-20200706080929-d51e80ef957d", Version: "v0.0.0-20200706080929-d51e80ef957d",
PURL: "pkg:golang/github.com/mgutz/ansi@v0.0.0-20200706080929-d51e80ef957d", PURL: "pkg:golang/github.com/mgutz/ansi@v0.0.0-20200706080929-d51e80ef957d",
Locations: file.NewLocationSet(file.NewLocation("go.mod")), Locations: file.NewLocationSet(file.NewLocation("go.mod")),
FoundBy: "go-module-file-cataloger", FoundBy: "go-module-file-cataloger",
Language: pkg.Go, Language: pkg.Go,
Type: pkg.GoModulePkg, Type: pkg.GoModulePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.GolangModuleEntry{ Metadata: pkg.GolangModuleEntry{
H1Digest: "h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=", H1Digest: "h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=",
}, },
+3 -1
View File
@@ -14,7 +14,9 @@ func newPackage(name, version string, m any, location file.Location) pkg.Package
PURL: packageURL(name, version), PURL: packageURL(name, version),
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Metadata: m, // in all cases (cabal, stack, etc.) we do not attempt to glean dependency information
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: m,
} }
p.SetID() p.SetID()
@@ -15,92 +15,103 @@ func TestParseCabalFreeze(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "Cabal", Name: "Cabal",
Version: "3.2.1.0", Version: "3.2.1.0",
PURL: "pkg:hackage/Cabal@3.2.1.0", PURL: "pkg:hackage/Cabal@3.2.1.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "Diff", Name: "Diff",
Version: "0.4.1", Version: "0.4.1",
PURL: "pkg:hackage/Diff@0.4.1", PURL: "pkg:hackage/Diff@0.4.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "HTTP", Name: "HTTP",
Version: "4000.3.16", Version: "4000.3.16",
PURL: "pkg:hackage/HTTP@4000.3.16", PURL: "pkg:hackage/HTTP@4000.3.16",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "HUnit", Name: "HUnit",
Version: "1.6.2.0", Version: "1.6.2.0",
PURL: "pkg:hackage/HUnit@1.6.2.0", PURL: "pkg:hackage/HUnit@1.6.2.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "OneTuple", Name: "OneTuple",
Version: "0.3.1", Version: "0.3.1",
PURL: "pkg:hackage/OneTuple@0.3.1", PURL: "pkg:hackage/OneTuple@0.3.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "Only", Name: "Only",
Version: "0.1", Version: "0.1",
PURL: "pkg:hackage/Only@0.1", PURL: "pkg:hackage/Only@0.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "PyF", Name: "PyF",
Version: "0.10.2.0", Version: "0.10.2.0",
PURL: "pkg:hackage/PyF@0.10.2.0", PURL: "pkg:hackage/PyF@0.10.2.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "QuickCheck", Name: "QuickCheck",
Version: "2.14.2", Version: "2.14.2",
PURL: "pkg:hackage/QuickCheck@2.14.2", PURL: "pkg:hackage/QuickCheck@2.14.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "RSA", Name: "RSA",
Version: "2.4.1", Version: "2.4.1",
PURL: "pkg:hackage/RSA@2.4.1", PURL: "pkg:hackage/RSA@2.4.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "SHA", Name: "SHA",
Version: "1.6.4.4", Version: "1.6.4.4",
PURL: "pkg:hackage/SHA@1.6.4.4", PURL: "pkg:hackage/SHA@1.6.4.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "Spock", Name: "Spock",
Version: "0.14.0.0", Version: "0.14.0.0",
PURL: "pkg:hackage/Spock@0.14.0.0", PURL: "pkg:hackage/Spock@0.14.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
} }
@@ -16,108 +16,117 @@ func TestParseStackLock(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "HTTP", Name: "HTTP",
Version: "4000.3.16", Version: "4000.3.16",
PURL: "pkg:hackage/HTTP@4000.3.16", PURL: "pkg:hackage/HTTP@4000.3.16",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "6042643c15a0b43e522a6693f1e322f05000d519543a84149cb80aeffee34f71", PkgHash: "6042643c15a0b43e522a6693f1e322f05000d519543a84149cb80aeffee34f71",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "configurator-pg", Name: "configurator-pg",
Version: "0.2.6", Version: "0.2.6",
PURL: "pkg:hackage/configurator-pg@0.2.6", PURL: "pkg:hackage/configurator-pg@0.2.6",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "cd9b06a458428e493a4d6def725af7ab1ab0fef678fbd871f9586fc7f9aa70be", PkgHash: "cd9b06a458428e493a4d6def725af7ab1ab0fef678fbd871f9586fc7f9aa70be",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "hasql-dynamic-statements", Name: "hasql-dynamic-statements",
Version: "0.3.1.1", Version: "0.3.1.1",
PURL: "pkg:hackage/hasql-dynamic-statements@0.3.1.1", PURL: "pkg:hackage/hasql-dynamic-statements@0.3.1.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "2cfe6e75990e690f595a87cbe553f2e90fcd738610f6c66749c81cc4396b2cc4", PkgHash: "2cfe6e75990e690f595a87cbe553f2e90fcd738610f6c66749c81cc4396b2cc4",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "hasql-implicits", Name: "hasql-implicits",
Version: "0.1.0.4", Version: "0.1.0.4",
PURL: "pkg:hackage/hasql-implicits@0.1.0.4", PURL: "pkg:hackage/hasql-implicits@0.1.0.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "0848d3cbc9d94e1e539948fa0be4d0326b26335034161bf8076785293444ca6f", PkgHash: "0848d3cbc9d94e1e539948fa0be4d0326b26335034161bf8076785293444ca6f",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "hasql-pool", Name: "hasql-pool",
Version: "0.5.2.2", Version: "0.5.2.2",
PURL: "pkg:hackage/hasql-pool@0.5.2.2", PURL: "pkg:hackage/hasql-pool@0.5.2.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "b56d4dea112d97a2ef4b2749508c0ca646828cb2d77b827e8dc433d249bb2062", PkgHash: "b56d4dea112d97a2ef4b2749508c0ca646828cb2d77b827e8dc433d249bb2062",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "lens-aeson", Name: "lens-aeson",
Version: "1.1.3", Version: "1.1.3",
PURL: "pkg:hackage/lens-aeson@1.1.3", PURL: "pkg:hackage/lens-aeson@1.1.3",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "52c8eaecd2d1c2a969c0762277c4a8ee72c339a686727d5785932e72ef9c3050", PkgHash: "52c8eaecd2d1c2a969c0762277c4a8ee72c339a686727d5785932e72ef9c3050",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "optparse-applicative", Name: "optparse-applicative",
Version: "0.16.1.0", Version: "0.16.1.0",
PURL: "pkg:hackage/optparse-applicative@0.16.1.0", PURL: "pkg:hackage/optparse-applicative@0.16.1.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "418c22ed6a19124d457d96bc66bd22c93ac22fad0c7100fe4972bbb4ac989731", PkgHash: "418c22ed6a19124d457d96bc66bd22c93ac22fad0c7100fe4972bbb4ac989731",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "protolude", Name: "protolude",
Version: "0.3.2", Version: "0.3.2",
PURL: "pkg:hackage/protolude@0.3.2", PURL: "pkg:hackage/protolude@0.3.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "2a38b3dad40d238ab644e234b692c8911423f9d3ed0e36b62287c4a698d92cd1", PkgHash: "2a38b3dad40d238ab644e234b692c8911423f9d3ed0e36b62287c4a698d92cd1",
SnapshotURL: url, SnapshotURL: url,
}, },
}, },
{ {
Name: "ptr", Name: "ptr",
Version: "0.16.8.2", Version: "0.16.8.2",
PURL: "pkg:hackage/ptr@0.16.8.2", PURL: "pkg:hackage/ptr@0.16.8.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlLockEntry{ Metadata: pkg.HackageStackYamlLockEntry{
PkgHash: "708ebb95117f2872d2c5a554eb6804cf1126e86abe793b2673f913f14e5eb1ac", PkgHash: "708ebb95117f2872d2c5a554eb6804cf1126e86abe793b2673f913f14e5eb1ac",
SnapshotURL: url, SnapshotURL: url,
@@ -15,89 +15,97 @@ func TestParseStackYaml(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "ShellCheck", Name: "ShellCheck",
Version: "0.8.0", Version: "0.8.0",
PURL: "pkg:hackage/ShellCheck@0.8.0", PURL: "pkg:hackage/ShellCheck@0.8.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "353c9322847b661e4c6f7c83c2acf8e5c08b682fbe516c7d46c29605937543df", PkgHash: "353c9322847b661e4c6f7c83c2acf8e5c08b682fbe516c7d46c29605937543df",
}, },
}, },
{ {
Name: "colourista", Name: "colourista",
Version: "0.1.0.1", Version: "0.1.0.1",
PURL: "pkg:hackage/colourista@0.1.0.1", PURL: "pkg:hackage/colourista@0.1.0.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "98353ee0e2f5d97d2148513f084c1cd37dfda03e48aa9dd7a017c9d9c0ba710e", PkgHash: "98353ee0e2f5d97d2148513f084c1cd37dfda03e48aa9dd7a017c9d9c0ba710e",
}, },
}, },
{ {
Name: "language-docker", Name: "language-docker",
Version: "11.0.0", Version: "11.0.0",
PURL: "pkg:hackage/language-docker@11.0.0", PURL: "pkg:hackage/language-docker@11.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "3406ff0c1d592490f53ead8cf2cd22bdf3d79fd125ccaf3add683f6d71c24d55", PkgHash: "3406ff0c1d592490f53ead8cf2cd22bdf3d79fd125ccaf3add683f6d71c24d55",
}, },
}, },
{ {
Name: "spdx", Name: "spdx",
Version: "1.0.0.2", Version: "1.0.0.2",
PURL: "pkg:hackage/spdx@1.0.0.2", PURL: "pkg:hackage/spdx@1.0.0.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "7dfac9b454ff2da0abb7560f0ffbe00ae442dd5cb76e8be469f77e6988a70fed", PkgHash: "7dfac9b454ff2da0abb7560f0ffbe00ae442dd5cb76e8be469f77e6988a70fed",
}, },
}, },
{ {
Name: "hspec", Name: "hspec",
Version: "2.9.4", Version: "2.9.4",
PURL: "pkg:hackage/hspec@2.9.4", PURL: "pkg:hackage/hspec@2.9.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "658a6a74d5a70c040edd6df2a12228c6d9e63082adaad1ed4d0438ad082a0ef3", PkgHash: "658a6a74d5a70c040edd6df2a12228c6d9e63082adaad1ed4d0438ad082a0ef3",
}, },
}, },
{ {
Name: "hspec-core", Name: "hspec-core",
Version: "2.9.4", Version: "2.9.4",
PURL: "pkg:hackage/hspec-core@2.9.4", PURL: "pkg:hackage/hspec-core@2.9.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "a126e9087409fef8dcafcd2f8656456527ac7bb163ed4d9cb3a57589042a5fe8", PkgHash: "a126e9087409fef8dcafcd2f8656456527ac7bb163ed4d9cb3a57589042a5fe8",
}, },
}, },
{ {
Name: "hspec-discover", Name: "hspec-discover",
Version: "2.9.4", Version: "2.9.4",
PURL: "pkg:hackage/hspec-discover@2.9.4", PURL: "pkg:hackage/hspec-discover@2.9.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "fbcf49ecfc3d4da53e797fd0275264cba776ffa324ee223e2a3f4ec2d2c9c4a6", PkgHash: "fbcf49ecfc3d4da53e797fd0275264cba776ffa324ee223e2a3f4ec2d2c9c4a6",
}, },
}, },
{ {
Name: "stm", Name: "stm",
Version: "2.5.0.2", Version: "2.5.0.2",
PURL: "pkg:hackage/stm@2.5.0.2", PURL: "pkg:hackage/stm@2.5.0.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.Haskell, Language: pkg.Haskell,
Type: pkg.HackagePkg, Type: pkg.HackagePkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.HackageStackYamlEntry{ Metadata: pkg.HackageStackYamlEntry{
PkgHash: "e4dc6473faaa75fbd7eccab4e3ee1d651d75bb0e49946ef0b8b751ccde771a55", PkgHash: "e4dc6473faaa75fbd7eccab4e3ee1d651d75bb0e49946ef0b8b751ccde771a55",
}, },
@@ -44,6 +44,7 @@ type CatalogTester struct {
licenseComparer cmptest.LicenseComparer licenseComparer cmptest.LicenseComparer
packageStringer func(pkg.Package) string packageStringer func(pkg.Package) string
customAssertions []func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) customAssertions []func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship)
ctx context.Context
} }
func NewCatalogTester() *CatalogTester { func NewCatalogTester() *CatalogTester {
@@ -106,6 +107,11 @@ func (p *CatalogTester) WithLinuxRelease(r linux.Release) *CatalogTester {
return p return p
} }
func (p *CatalogTester) WithContext(ctx context.Context) *CatalogTester {
p.ctx = ctx
return p
}
func (p *CatalogTester) WithEnv(env *generic.Environment) *CatalogTester { func (p *CatalogTester) WithEnv(env *generic.Environment) *CatalogTester {
p.env = env p.env = env
return p return p
@@ -236,7 +242,14 @@ func (p *CatalogTester) TestCataloger(t *testing.T, cataloger pkg.Cataloger) {
resolver := NewObservingResolver(p.resolver) resolver := NewObservingResolver(p.resolver)
pkgs, relationships, err := cataloger.Catalog(context.Background(), resolver) var ctx context.Context
if p.ctx != nil {
ctx = p.ctx
} else {
ctx = context.Background()
}
pkgs, relationships, err := cataloger.Catalog(ctx, resolver)
// this is a minimum set, the resolver may return more that just this list // this is a minimum set, the resolver may return more that just this list
for _, path := range p.expectedPathResponses { for _, path := range p.expectedPathResponses {
@@ -437,6 +437,7 @@ func TestParseJar(t *testing.T) {
} }
func TestParseNestedJar(t *testing.T) { func TestParseNestedJar(t *testing.T) {
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
tests := []struct { tests := []struct {
fixture string fixture string
expected []pkg.Package expected []pkg.Package
@@ -638,7 +639,7 @@ func TestParseNestedJar(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
gap := newGenericArchiveParserAdapter(ArchiveCatalogerConfig{}) gap := newGenericArchiveParserAdapter(ArchiveCatalogerConfig{})
actual, _, err := gap.processJavaArchive(context.Background(), file.LocationReadCloser{ actual, _, err := gap.processJavaArchive(ctx, file.LocationReadCloser{
Location: file.NewLocation(fixture.Name()), Location: file.NewLocation(fixture.Name()),
ReadCloser: fixture, ReadCloser: fixture,
}, nil) }, nil)
@@ -1166,6 +1167,8 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
}, },
} }
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
tests := []struct { tests := []struct {
name string name string
fixtureName string fixtureName string
@@ -1355,6 +1358,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
pkgtest.NewCatalogTester(). pkgtest.NewCatalogTester().
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName, tt.fileExtension)). FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName, tt.fileExtension)).
Expects(tt.expectedPkgs, tt.expectedRelationships). Expects(tt.expectedPkgs, tt.expectedRelationships).
WithContext(ctx).
WithCompareOptions( WithCompareOptions(
cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"), cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"),
cmp.Comparer(func(x, y pkg.KeyValue) bool { cmp.Comparer(func(x, y pkg.KeyValue) bool {
+16 -9
View File
@@ -1,8 +1,10 @@
package java package java
import ( import (
"context"
"testing" "testing"
"github.com/anchore/syft/internal/licenses"
"github.com/anchore/syft/syft/cataloging" "github.com/anchore/syft/syft/cataloging"
"github.com/anchore/syft/syft/cpe" "github.com/anchore/syft/syft/cpe"
"github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/file"
@@ -11,6 +13,8 @@ import (
) )
func Test_ArchiveCataloger_Globs(t *testing.T) { func Test_ArchiveCataloger_Globs(t *testing.T) {
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
tests := []struct { tests := []struct {
name string name string
fixture string fixture string
@@ -59,6 +63,7 @@ func Test_ArchiveCataloger_Globs(t *testing.T) {
pkgtest.NewCatalogTester(). pkgtest.NewCatalogTester().
FromDirectory(t, test.fixture). FromDirectory(t, test.fixture).
ExpectsResolverContentQueries(test.expected). ExpectsResolverContentQueries(test.expected).
WithContext(ctx).
TestCataloger(t, TestCataloger(t,
NewArchiveCataloger( NewArchiveCataloger(
ArchiveCatalogerConfig{ ArchiveCatalogerConfig{
@@ -128,7 +133,8 @@ func TestJvmDistributionCataloger(t *testing.T) {
cpe.Must("cpe:2.3:a:oracle:jre:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource), cpe.Must("cpe:2.3:a:oracle:jre:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource),
cpe.Must("cpe:2.3:a:oracle:jdk:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource), cpe.Must("cpe:2.3:a:oracle:jdk:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource),
}, },
PURL: "pkg:generic/oracle/jdk@1.8.0_411-b25", PURL: "pkg:generic/oracle/jdk@1.8.0_411-b25",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaVMInstallation{ Metadata: pkg.JavaVMInstallation{
Release: pkg.JavaVMRelease{ Release: pkg.JavaVMRelease{
JavaRuntimeVersion: "1.8.0_411-b25", JavaRuntimeVersion: "1.8.0_411-b25",
@@ -150,14 +156,15 @@ func TestJvmDistributionCataloger(t *testing.T) {
name: "valid post-jep223", name: "valid post-jep223",
fixture: "test-fixtures/jvm-installs/valid-post-jep223", fixture: "test-fixtures/jvm-installs/valid-post-jep223",
expected: pkg.Package{ expected: pkg.Package{
Name: "openjdk", Name: "openjdk",
Version: "21.0.4+7-LTS", Version: "21.0.4+7-LTS",
FoundBy: "java-jvm-cataloger", FoundBy: "java-jvm-cataloger",
Locations: file.NewLocationSet(file.NewLocation("jvm/openjdk/release")), Locations: file.NewLocationSet(file.NewLocation("jvm/openjdk/release")),
Licenses: pkg.NewLicenseSet(), Licenses: pkg.NewLicenseSet(),
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:oracle:openjdk:21.0.4:*:*:*:*:*:*:*", cpe.DeclaredSource)}, CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:oracle:openjdk:21.0.4:*:*:*:*:*:*:*", cpe.DeclaredSource)},
PURL: "pkg:generic/oracle/openjdk@21.0.4%2B7-LTS?repository_url=https://github.com/adoptium/jdk21u.git", PURL: "pkg:generic/oracle/openjdk@21.0.4%2B7-LTS?repository_url=https://github.com/adoptium/jdk21u.git",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaVMInstallation{ Metadata: pkg.JavaVMInstallation{
Release: pkg.JavaVMRelease{ Release: pkg.JavaVMRelease{
Implementor: "Eclipse Adoptium", Implementor: "Eclipse Adoptium",
@@ -23,17 +23,17 @@ type lockfileDependency struct {
func parseGradleLockfile(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { func parseGradleLockfile(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
var pkgs []pkg.Package var pkgs []pkg.Package
// Create a new scanner to read the file // create a new scanner to read the file
scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(reader)
// Create slices to hold the dependencies and plugins // create slices to hold the dependencies and plugins
dependencies := []lockfileDependency{} dependencies := []lockfileDependency{}
// Loop over all lines in the file // loop over all lines in the file
for scanner.Scan() { for scanner.Scan() {
line := scanner.Text() line := scanner.Text()
// Trim leading and trailing whitespace from the line // trim leading and trailing whitespace from the line
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
groupNameVersion := line groupNameVersion := line
@@ -42,7 +42,7 @@ func parseGradleLockfile(_ context.Context, _ file.Resolver, _ *generic.Environm
// we have a version directly specified // we have a version directly specified
if len(parts) == 3 { if len(parts) == 3 {
// Create a new Dependency struct and add it to the dependencies slice // create a new Dependency struct and add it to the dependencies slice
dep := lockfileDependency{Group: parts[0], Name: parts[1], Version: parts[2]} dep := lockfileDependency{Group: parts[0], Name: parts[1], Version: parts[2]}
dependencies = append(dependencies, dep) dependencies = append(dependencies, dep)
} }
@@ -68,7 +68,9 @@ func parseGradleLockfile(_ context.Context, _ file.Resolver, _ *generic.Environm
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
PURL: packageURL(dep.Name, dep.Version, archive), PURL: packageURL(dep.Name, dep.Version, archive),
Metadata: archive, // though we do have dependencies listed, we do not have them related to one another, thus we must answer unknown
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: archive,
} }
mappedPkg.SetID() mappedPkg.SetID()
pkgs = append(pkgs, mappedPkg) pkgs = append(pkgs, mappedPkg)
@@ -17,41 +17,45 @@ func Test_parserGradleLockfile(t *testing.T) {
input: "test-fixtures/gradle/gradle.lockfile", input: "test-fixtures/gradle/gradle.lockfile",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "commons-text", Name: "commons-text",
Version: "1.8", Version: "1.8",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
PURL: "pkg:maven/org.apache.commons/commons-text@1.8", PURL: "pkg:maven/org.apache.commons/commons-text@1.8",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{GroupID: "org.apache.commons", ArtifactID: "commons-text", Version: "1.8", Name: "commons-text"}, PomProject: &pkg.JavaPomProject{GroupID: "org.apache.commons", ArtifactID: "commons-text", Version: "1.8", Name: "commons-text"},
}, },
}, },
{ {
Name: "hamcrest-core", Name: "hamcrest-core",
Version: "1.3", Version: "1.3",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
PURL: "pkg:maven/org.hamcrest/hamcrest-core@1.3", PURL: "pkg:maven/org.hamcrest/hamcrest-core@1.3",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{GroupID: "org.hamcrest", ArtifactID: "hamcrest-core", Version: "1.3", Name: "hamcrest-core"}, PomProject: &pkg.JavaPomProject{GroupID: "org.hamcrest", ArtifactID: "hamcrest-core", Version: "1.3", Name: "hamcrest-core"},
}, },
}, },
{ {
Name: "joda-time", Name: "joda-time",
Version: "2.2", Version: "2.2",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
PURL: "pkg:maven/joda-time/joda-time@2.2", PURL: "pkg:maven/joda-time/joda-time@2.2",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{GroupID: "joda-time", ArtifactID: "joda-time", Version: "2.2", Name: "joda-time"}, PomProject: &pkg.JavaPomProject{GroupID: "joda-time", ArtifactID: "joda-time", Version: "2.2", Name: "joda-time"},
}, },
}, },
{ {
Name: "junit", Name: "junit",
Version: "4.12", Version: "4.12",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
PURL: "pkg:maven/junit/junit@4.12", PURL: "pkg:maven/junit/junit@4.12",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{GroupID: "junit", ArtifactID: "junit", Version: "4.12", Name: "junit"}, PomProject: &pkg.JavaPomProject{GroupID: "junit", ArtifactID: "junit", Version: "4.12", Name: "junit"},
}, },
@@ -98,6 +98,8 @@ func parseJVMRelease(_ context.Context, resolver file.Resolver, _ *generic.Envir
PURL: jvmPurl(*ri, version, vendor, product), PURL: jvmPurl(*ri, version, vendor, product),
Licenses: licenses, Licenses: licenses,
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
// we don't have any dependency information about the JVM package itself
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaVMInstallation{ Metadata: pkg.JavaVMInstallation{
Release: *ri, Release: *ri,
Files: files, Files: files,
+46 -11
View File
@@ -51,7 +51,7 @@ func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver
r.AddPom(ctx, pom, pomLocation) r.AddPom(ctx, pom, pomLocation)
} }
var pkgs []pkg.Package var pkgs []*pkg.Package
var relationships []artifact.Relationship var relationships []artifact.Relationship
resolved := map[maven.ID]*pkg.Package{} resolved := map[maven.ID]*pkg.Package{}
@@ -65,7 +65,7 @@ func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver
continue continue
} }
resolved[id] = mainPkg resolved[id] = mainPkg
pkgs = append(pkgs, *mainPkg) pkgs = append(pkgs, mainPkg)
} }
// catalog all dependencies // catalog all dependencies
@@ -81,7 +81,27 @@ func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver
errs = unknown.Join(errs, newErrs) errs = unknown.Join(errs, newErrs)
} }
return pkgs, relationships, errs return finalizePackages(pkgs), finalizeRelationships(relationships), errs
}
func finalizeRelationships(relationships []artifact.Relationship) []artifact.Relationship {
for i := range relationships {
if f, ok := relationships[i].From.(*pkg.Package); ok {
relationships[i].From = *f
}
if t, ok := relationships[i].To.(*pkg.Package); ok {
relationships[i].To = *t
}
}
return relationships
}
func finalizePackages(pkgs []*pkg.Package) []pkg.Package {
var values []pkg.Package
for i := range pkgs {
values = append(values, *pkgs[i])
}
return values
} }
func readPomFromLocation(fileResolver file.Resolver, pomLocation file.Location) (*maven.Project, error) { func readPomFromLocation(fileResolver file.Resolver, pomLocation file.Location) (*maven.Project, error) {
@@ -142,7 +162,10 @@ func newPackageFromMavenPom(ctx context.Context, r *maven.Resolver, pom *maven.P
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
PURL: packageURL(id.ArtifactID, id.Version, m), PURL: packageURL(id.ArtifactID, id.Version, m),
Metadata: m, // later in processing we may resolve the dependencies for this package (e.g. online enrichment)
// but at this point there is not enough information to claim we have complete dependency information
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: m,
} }
finalizePackage(p) finalizePackage(p)
@@ -150,9 +173,9 @@ func newPackageFromMavenPom(ctx context.Context, r *maven.Resolver, pom *maven.P
return p return p
} }
func collectDependencies(ctx context.Context, r *maven.Resolver, resolved map[maven.ID]*pkg.Package, parentPkg *pkg.Package, pom *maven.Project, loc file.Location, includeTransitiveDependencies bool) ([]pkg.Package, []artifact.Relationship, error) { func collectDependencies(ctx context.Context, r *maven.Resolver, resolved map[maven.ID]*pkg.Package, parentPkg *pkg.Package, pom *maven.Project, loc file.Location, includeTransitiveDependencies bool) ([]*pkg.Package, []artifact.Relationship, error) {
var errs error var errs error
var pkgs []pkg.Package var pkgs []*pkg.Package
var relationships []artifact.Relationship var relationships []artifact.Relationship
pomID := r.ResolveID(ctx, pom) pomID := r.ResolveID(ctx, pom)
@@ -196,16 +219,25 @@ func collectDependencies(ctx context.Context, r *maven.Resolver, resolved map[ma
} }
} }
pkgs = append(pkgs, *depPkg) pkgs = append(pkgs, depPkg)
if parentPkg != nil { if parentPkg != nil {
relationships = append(relationships, artifact.Relationship{ relationships = append(relationships, artifact.Relationship{ //nolint:gocritic // we intentionally want to use the reference to the package which will still be mutated and finalized to a value later
From: *depPkg, // both the to and from packages may be mutated based on the resolved dependencies, so we need references to these values
To: *parentPkg, // to ensure the nodes used are consistent with the final state of the packages.
// note: it is VITAL that these references are replaced with values by the caller of this function before using
// these relationships in the cataloger output.
From: depPkg,
To: parentPkg,
Type: artifact.DependencyOfRelationship, Type: artifact.DependencyOfRelationship,
}) })
} }
} }
// as long as we have no errors, we can claim we have complete direct dependencies (even if there are none)
if errs == nil {
parentPkg.Dependencies = pkg.CompleteDependencies
}
return pkgs, relationships, errs return pkgs, relationships, errs
} }
@@ -270,7 +302,10 @@ func newPackageFromDependency(ctx context.Context, r *maven.Resolver, pom *maven
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, // TODO: should we differentiate between packages from jar/war/zip versus packages from a pom.xml that were not installed yet? Type: pkg.JavaPkg, // TODO: should we differentiate between packages from jar/war/zip versus packages from a pom.xml that were not installed yet?
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Metadata: m, // later in processing we may resolve the dependencies for this package (e.g. online enrichment) but
// by default we cannot claim we have complete dependency information
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: m,
} }
finalizePackage(p) finalizePackage(p)
+119 -93
View File
@@ -24,13 +24,14 @@ func Test_parsePomXML(t *testing.T) {
pomLocation := file.NewLocationSet(file.NewLocation("pom.xml")) pomLocation := file.NewLocationSet(file.NewLocation("pom.xml"))
exampleJavaAppMaven := pkg.Package{ exampleJavaAppMaven := pkg.Package{
Name: "example-java-app-maven", Name: "example-java-app-maven",
Version: "0.1.0", Version: "0.1.0",
PURL: "pkg:maven/org.anchore/example-java-app-maven@0.1.0", PURL: "pkg:maven/org.anchore/example-java-app-maven@0.1.0",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Locations: pomLocation, Locations: pomLocation,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{ PomProject: &pkg.JavaPomProject{
GroupID: "org.anchore", GroupID: "org.anchore",
@@ -42,13 +43,14 @@ func Test_parsePomXML(t *testing.T) {
finalizePackage(&exampleJavaAppMaven) finalizePackage(&exampleJavaAppMaven)
jodaTime := pkg.Package{ jodaTime := pkg.Package{
Name: "joda-time", Name: "joda-time",
Version: "2.9.2", Version: "2.9.2",
PURL: "pkg:maven/com.joda/joda-time@2.9.2", PURL: "pkg:maven/com.joda/joda-time@2.9.2",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Locations: pomLocation, Locations: pomLocation,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "com.joda", GroupID: "com.joda",
@@ -59,13 +61,14 @@ func Test_parsePomXML(t *testing.T) {
finalizePackage(&jodaTime) finalizePackage(&jodaTime)
junit := pkg.Package{ junit := pkg.Package{
Name: "junit", Name: "junit",
Version: "4.12", Version: "4.12",
PURL: "pkg:maven/junit/junit@4.12", PURL: "pkg:maven/junit/junit@4.12",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Locations: pomLocation, Locations: pomLocation,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "junit", GroupID: "junit",
@@ -472,12 +475,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
pomXmlLocation := file.NewLocationSet(file.NewLocation("pom.xml")) pomXmlLocation := file.NewLocationSet(file.NewLocation("pom.xml"))
commonsText := pkg.Package{ commonsText := pkg.Package{
Name: "commons-text", Name: "commons-text",
Version: "1.10.0", Version: "1.10.0",
PURL: "pkg:maven/org.apache.commons/commons-text@1.10.0", PURL: "pkg:maven/org.apache.commons/commons-text@1.10.0",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{ PomProject: &pkg.JavaPomProject{
Parent: &pkg.JavaPomParent{ Parent: &pkg.JavaPomParent{
@@ -496,12 +500,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
commonsLang3 := pkg.Package{ commonsLang3 := pkg.Package{
Name: "commons-lang3", Name: "commons-lang3",
Version: "3.12.0", Version: "3.12.0",
PURL: "pkg:maven/org.apache.commons/commons-lang3@3.12.0", PURL: "pkg:maven/org.apache.commons/commons-lang3@3.12.0",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
@@ -511,12 +516,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
junitJupiter := pkg.Package{ junitJupiter := pkg.Package{
Name: "junit-jupiter", Name: "junit-jupiter",
Version: "", Version: "",
PURL: "pkg:maven/org.junit.jupiter/junit-jupiter", PURL: "pkg:maven/org.junit.jupiter/junit-jupiter",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.junit.jupiter", GroupID: "org.junit.jupiter",
@@ -527,12 +533,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
assertjCore := pkg.Package{ assertjCore := pkg.Package{
Name: "assertj-core", Name: "assertj-core",
Version: "3.23.1", Version: "3.23.1",
PURL: "pkg:maven/org.assertj/assertj-core@3.23.1", PURL: "pkg:maven/org.assertj/assertj-core@3.23.1",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.assertj", GroupID: "org.assertj",
@@ -543,12 +550,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
commonsIO := pkg.Package{ commonsIO := pkg.Package{
Name: "commons-io", Name: "commons-io",
Version: "2.11.0", Version: "2.11.0",
PURL: "pkg:maven/commons-io/commons-io@2.11.0", PURL: "pkg:maven/commons-io/commons-io@2.11.0",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "commons-io", GroupID: "commons-io",
@@ -559,12 +567,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
mockitoInline := pkg.Package{ mockitoInline := pkg.Package{
Name: "mockito-inline", Name: "mockito-inline",
Version: "4.8.0", Version: "4.8.0",
PURL: "pkg:maven/org.mockito/mockito-inline@4.8.0", PURL: "pkg:maven/org.mockito/mockito-inline@4.8.0",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.mockito", GroupID: "org.mockito",
@@ -575,12 +584,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
js := pkg.Package{ js := pkg.Package{
Name: "js", Name: "js",
Version: "22.0.0.2", Version: "22.0.0.2",
PURL: "pkg:maven/org.graalvm.js/js@22.0.0.2", PURL: "pkg:maven/org.graalvm.js/js@22.0.0.2",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.graalvm.js", GroupID: "org.graalvm.js",
@@ -591,12 +601,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
jsScriptengine := pkg.Package{ jsScriptengine := pkg.Package{
Name: "js-scriptengine", Name: "js-scriptengine",
Version: "22.0.0.2", Version: "22.0.0.2",
PURL: "pkg:maven/org.graalvm.js/js-scriptengine@22.0.0.2", PURL: "pkg:maven/org.graalvm.js/js-scriptengine@22.0.0.2",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.graalvm.js", GroupID: "org.graalvm.js",
@@ -607,12 +618,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
commonsRngSimple := pkg.Package{ commonsRngSimple := pkg.Package{
Name: "commons-rng-simple", Name: "commons-rng-simple",
Version: "1.4", Version: "1.4",
PURL: "pkg:maven/org.apache.commons/commons-rng-simple@1.4", PURL: "pkg:maven/org.apache.commons/commons-rng-simple@1.4",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
@@ -623,12 +635,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
jmhCore := pkg.Package{ jmhCore := pkg.Package{
Name: "jmh-core", Name: "jmh-core",
Version: "1.35", Version: "1.35",
PURL: "pkg:maven/org.openjdk.jmh/jmh-core@1.35", PURL: "pkg:maven/org.openjdk.jmh/jmh-core@1.35",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.openjdk.jmh", GroupID: "org.openjdk.jmh",
@@ -639,12 +652,13 @@ func getCommonsTextExpectedPackages(resolved bool) expected {
} }
jmhGeneratorAnnprocess := pkg.Package{ jmhGeneratorAnnprocess := pkg.Package{
Name: "jmh-generator-annprocess", Name: "jmh-generator-annprocess",
Version: "1.35", Version: "1.35",
PURL: "pkg:maven/org.openjdk.jmh/jmh-generator-annprocess@1.35", PURL: "pkg:maven/org.openjdk.jmh/jmh-generator-annprocess@1.35",
Language: pkg.Java, Language: pkg.Java,
Type: pkg.JavaPkg, Type: pkg.JavaPkg,
FoundBy: pomCatalogerName, FoundBy: pomCatalogerName,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.openjdk.jmh", GroupID: "org.openjdk.jmh",
@@ -699,6 +713,8 @@ func expectedTransientPackageData() expected {
transitiveTopLevel := pkg.Package{ transitiveTopLevel := pkg.Package{
Name: "transitive-top-level", Name: "transitive-top-level",
Version: "99", Version: "99",
// one of the children is missing a pom in the test fixtures, this is a search miss
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{ PomProject: &pkg.JavaPomProject{
GroupID: "my.other.group", GroupID: "my.other.group",
@@ -708,9 +724,10 @@ func expectedTransientPackageData() expected {
}, },
} }
childOne := pkg.Package{ childOne := pkg.Package{
Name: "child-one", Name: "child-one",
Version: "1.3.6", Version: "1.3.6",
Licenses: epl2, Licenses: epl2,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{ PomProject: &pkg.JavaPomProject{
GroupID: "my.org", GroupID: "my.org",
@@ -729,9 +746,10 @@ func expectedTransientPackageData() expected {
}, },
} }
childTwo := pkg.Package{ childTwo := pkg.Package{
Name: "child-two", Name: "child-two",
Version: "2.1.90", Version: "2.1.90",
Licenses: epl2, Licenses: epl2,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProject: &pkg.JavaPomProject{ PomProject: &pkg.JavaPomProject{
GroupID: "my.org", GroupID: "my.org",
@@ -753,6 +771,8 @@ func expectedTransientPackageData() expected {
commonsLang3_113_7_8_0 := pkg.Package{ commonsLang3_113_7_8_0 := pkg.Package{
Name: "commons-lang3", Name: "commons-lang3",
Version: "3.113.7.8.0", Version: "3.113.7.8.0",
// missing pom in test fixtures, this is a search miss
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
@@ -763,6 +783,8 @@ func expectedTransientPackageData() expected {
commonsLang3_12_0 := pkg.Package{ commonsLang3_12_0 := pkg.Package{
Name: "commons-lang3", Name: "commons-lang3",
Version: "3.12.0", Version: "3.12.0",
// missing pom in test fixtures, this is a search miss
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
@@ -773,6 +795,8 @@ func expectedTransientPackageData() expected {
commonsMath3 := pkg.Package{ commonsMath3 := pkg.Package{
Name: "commons-math3.11.0", Name: "commons-math3.11.0",
Version: "3.5", Version: "3.5",
// missing pom in test fixtures, this is a search miss
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
@@ -783,6 +807,8 @@ func expectedTransientPackageData() expected {
commonsExec := pkg.Package{ commonsExec := pkg.Package{
Name: "commons-exec", Name: "commons-exec",
Version: "1.3", Version: "1.3",
// missing pom in test fixtures, this is a search miss
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.JavaArchive{ Metadata: pkg.JavaArchive{
PomProperties: &pkg.JavaPomProperties{ PomProperties: &pkg.JavaPomProperties{
GroupID: "org.apache.commons", GroupID: "org.apache.commons",
+97 -86
View File
@@ -12,120 +12,131 @@ func Test_JavascriptCataloger(t *testing.T) {
locationSet := file.NewLocationSet(file.NewLocation("package-lock.json")) locationSet := file.NewLocationSet(file.NewLocation("package-lock.json"))
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "@actions/core", Name: "@actions/core",
Version: "1.6.0", Version: "1.6.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/%40actions/core@1.6.0", PURL: "pkg:npm/%40actions/core@1.6.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation("package-lock.json")), pkg.NewLicenseFromLocations("MIT", file.NewLocation("package-lock.json")),
), ),
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="}, Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="},
}, },
{ {
Name: "ansi-regex", Name: "ansi-regex",
Version: "3.0.0", Version: "3.0.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/ansi-regex@3.0.0", PURL: "pkg:npm/ansi-regex@3.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="},
}, },
{ {
Name: "cowsay", Name: "cowsay",
Version: "1.4.0", Version: "1.4.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/cowsay@1.4.0", PURL: "pkg:npm/cowsay@1.4.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation("package-lock.json")), pkg.NewLicenseFromLocations("MIT", file.NewLocation("package-lock.json")),
), ),
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="}, Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="},
}, },
{ {
Name: "get-stdin", Name: "get-stdin",
Version: "5.0.1", Version: "5.0.1",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/get-stdin@5.0.1", PURL: "pkg:npm/get-stdin@5.0.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="},
}, },
{ {
Name: "is-fullwidth-code-point", Name: "is-fullwidth-code-point",
Version: "2.0.0", Version: "2.0.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/is-fullwidth-code-point@2.0.0", PURL: "pkg:npm/is-fullwidth-code-point@2.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="},
}, },
{ {
Name: "minimist", Name: "minimist",
Version: "0.0.10", Version: "0.0.10",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/minimist@0.0.10", PURL: "pkg:npm/minimist@0.0.10",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="},
}, },
{ {
Name: "optimist", Name: "optimist",
Version: "0.6.1", Version: "0.6.1",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/optimist@0.6.1", PURL: "pkg:npm/optimist@0.6.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="},
}, },
{ {
Name: "string-width", Name: "string-width",
Version: "2.1.1", Version: "2.1.1",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/string-width@2.1.1", PURL: "pkg:npm/string-width@2.1.1",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="},
}, },
{ {
Name: "strip-ansi", Name: "strip-ansi",
Version: "4.0.0", Version: "4.0.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/strip-ansi@4.0.0", PURL: "pkg:npm/strip-ansi@4.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="},
}, },
{ {
Name: "strip-eof", Name: "strip-eof",
Version: "1.0.0", Version: "1.0.0",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/strip-eof@1.0.0", PURL: "pkg:npm/strip-eof@1.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="},
}, },
{ {
Name: "wordwrap", Name: "wordwrap",
Version: "0.0.3", Version: "0.0.3",
FoundBy: "javascript-lock-cataloger", FoundBy: "javascript-lock-cataloger",
PURL: "pkg:npm/wordwrap@0.0.3", PURL: "pkg:npm/wordwrap@0.0.3",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="},
}, },
} }
+18 -3
View File
@@ -32,6 +32,9 @@ func newPackageJSONPackage(u packageJSON, indexLocation file.Location) pkg.Packa
Language: pkg.JavaScript, Language: pkg.JavaScript,
Licenses: pkg.NewLicenseSet(license...), Licenses: pkg.NewLicenseSet(license...),
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
// though we could glean dependency information from the package.json and surrounding packages found in a node_modules directory,
// we do not do so today, so we record "unknown" for this package's dependency completeness field.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: u.Name, Name: u.Name,
Version: u.Version, Version: u.Version,
@@ -88,7 +91,10 @@ func newPackageLockV1Package(cfg CatalogerConfig, resolver file.Resolver, locati
PURL: packageURL(name, version), PURL: packageURL(name, version),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: u.Resolved, Integrity: u.Integrity}, // though we could glean dependency information from the package-lock.json,
// we do not do so today, so we record "unknown" for this package's dependency completeness field.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: u.Resolved, Integrity: u.Integrity},
}, },
) )
} }
@@ -120,7 +126,10 @@ func newPackageLockV2Package(cfg CatalogerConfig, resolver file.Resolver, locati
PURL: packageURL(name, u.Version), PURL: packageURL(name, u.Version),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: u.Resolved, Integrity: u.Integrity}, // though we could glean dependency information from the package-lock.json,
// we do not do so today, so we record "unknown" for this package's dependency completeness field.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: u.Resolved, Integrity: u.Integrity},
}, },
) )
} }
@@ -136,6 +145,9 @@ func newPnpmPackage(resolver file.Resolver, location file.Location, name, versio
PURL: packageURL(name, version), PURL: packageURL(name, version),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
// though we could glean dependency information from the pnpm files,
// we do not do so today, so we record "unknown" for this package's dependency completeness field.
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
) )
} }
@@ -164,7 +176,10 @@ func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location fi
PURL: packageURL(name, version), PURL: packageURL(name, version),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{Resolved: resolved, Integrity: integrity}, // though we could glean dependency information from the yarn.lock,
// we do not do so today, so we record "unknown" for this package's dependency completeness field.
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{Resolved: resolved, Integrity: integrity},
}, },
) )
} }
@@ -26,6 +26,7 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package.json")), pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package.json")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -47,6 +48,7 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("ISC", file.NewLocation("test-fixtures/pkg-json/package-license-object.json")), pkg.NewLicenseFromLocations("ISC", file.NewLocation("test-fixtures/pkg-json/package-license-object.json")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -68,7 +70,8 @@ func TestParsePackageJSON(t *testing.T) {
pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")), pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")),
pkg.NewLicenseFromLocations("Apache-2.0", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")), pkg.NewLicenseFromLocations("Apache-2.0", file.NewLocation("test-fixtures/pkg-json/package-license-objects.json")),
), ),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -82,11 +85,12 @@ func TestParsePackageJSON(t *testing.T) {
{ {
Fixture: "test-fixtures/pkg-json/package-malformed-license.json", Fixture: "test-fixtures/pkg-json/package-malformed-license.json",
ExpectedPkg: pkg.Package{ ExpectedPkg: pkg.Package{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
PURL: "pkg:npm/npm@6.14.6", PURL: "pkg:npm/npm@6.14.6",
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -100,11 +104,12 @@ func TestParsePackageJSON(t *testing.T) {
{ {
Fixture: "test-fixtures/pkg-json/package-no-license.json", Fixture: "test-fixtures/pkg-json/package-no-license.json",
ExpectedPkg: pkg.Package{ ExpectedPkg: pkg.Package{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
PURL: "pkg:npm/npm@6.14.6", PURL: "pkg:npm/npm@6.14.6",
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -125,7 +130,8 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-nested-author.json")), pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-nested-author.json")),
), ),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -146,7 +152,8 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/pkg-json/package-repo-string.json")), pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/pkg-json/package-repo-string.json")),
), ),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "function-bind", Name: "function-bind",
Version: "1.1.1", Version: "1.1.1",
@@ -167,7 +174,8 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-private.json")), pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-private.json")),
), ),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -189,7 +197,8 @@ func TestParsePackageJSON(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-author-non-standard.json")), pkg.NewLicenseFromLocations("Artistic-2.0", file.NewLocation("test-fixtures/pkg-json/package-author-non-standard.json")),
), ),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{ Metadata: pkg.NpmPackage{
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
@@ -224,11 +233,12 @@ func TestParsePackageJSON_Partial(t *testing.T) { // see https://github.com/anch
// according to compliance rules later // according to compliance rules later
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: packageURL("", ""), PURL: packageURL("", ""),
Metadata: pkg.NpmPackage{}, Locations: file.NewLocationSet(file.NewLocation(fixtureFile)),
Locations: file.NewLocationSet(file.NewLocation(fixtureFile)), Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackage{},
}, },
} }
pkgtest.TestFileParser(t, fixtureFile, parsePackageJSON, expectedPkgs, nil) pkgtest.TestFileParser(t, fixtureFile, parsePackageJSON, expectedPkgs, nil)
@@ -13,92 +13,103 @@ func TestParsePackageLock(t *testing.T) {
var expectedRelationships []artifact.Relationship var expectedRelationships []artifact.Relationship
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "@actions/core", Name: "@actions/core",
Version: "1.6.0", Version: "1.6.0",
PURL: "pkg:npm/%40actions/core@1.6.0", PURL: "pkg:npm/%40actions/core@1.6.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", Integrity: "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw=="},
}, },
{ {
Name: "ansi-regex", Name: "ansi-regex",
Version: "3.0.0", Version: "3.0.0",
PURL: "pkg:npm/ansi-regex@3.0.0", PURL: "pkg:npm/ansi-regex@3.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", Integrity: "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="},
}, },
{ {
Name: "cowsay", Name: "cowsay",
Version: "1.4.0", Version: "1.4.0",
PURL: "pkg:npm/cowsay@1.4.0", PURL: "pkg:npm/cowsay@1.4.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/cowsay/-/cowsay-1.4.0.tgz", Integrity: "sha512-rdg5k5PsHFVJheO/pmE3aDg2rUDDTfPJau6yYkZYlHFktUz+UxbE+IgnUAEyyCyv4noL5ltxXD0gZzmHPCy/9g=="},
}, },
{ {
Name: "get-stdin", Name: "get-stdin",
Version: "5.0.1", Version: "5.0.1",
PURL: "pkg:npm/get-stdin@5.0.1", PURL: "pkg:npm/get-stdin@5.0.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", Integrity: "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="},
}, },
{ {
Name: "is-fullwidth-code-point", Name: "is-fullwidth-code-point",
Version: "2.0.0", Version: "2.0.0",
PURL: "pkg:npm/is-fullwidth-code-point@2.0.0", PURL: "pkg:npm/is-fullwidth-code-point@2.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", Integrity: "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="},
}, },
{ {
Name: "minimist", Name: "minimist",
Version: "0.0.10", Version: "0.0.10",
PURL: "pkg:npm/minimist@0.0.10", PURL: "pkg:npm/minimist@0.0.10",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", Integrity: "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="},
}, },
{ {
Name: "optimist", Name: "optimist",
Version: "0.6.1", Version: "0.6.1",
PURL: "pkg:npm/optimist@0.6.1", PURL: "pkg:npm/optimist@0.6.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", Integrity: "sha1-2j6nRob6IaGaERwybpDrFaAZZoY="},
}, },
{ {
Name: "string-width", Name: "string-width",
Version: "2.1.1", Version: "2.1.1",
PURL: "pkg:npm/string-width@2.1.1", PURL: "pkg:npm/string-width@2.1.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", Integrity: "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw=="},
}, },
{ {
Name: "strip-ansi", Name: "strip-ansi",
Version: "4.0.0", Version: "4.0.0",
PURL: "pkg:npm/strip-ansi@4.0.0", PURL: "pkg:npm/strip-ansi@4.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", Integrity: "sha1-qEeQIusaw2iocTibY1JixQXuNo8="},
}, },
{ {
Name: "strip-eof", Name: "strip-eof",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:npm/strip-eof@1.0.0", PURL: "pkg:npm/strip-eof@1.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", Integrity: "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="},
}, },
{ {
Name: "wordwrap", Name: "wordwrap",
Version: "0.0.3", Version: "0.0.3",
PURL: "pkg:npm/wordwrap@0.0.3", PURL: "pkg:npm/wordwrap@0.0.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", Integrity: "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="},
}, },
} }
fixture := "test-fixtures/pkg-lock/package-lock.json" fixture := "test-fixtures/pkg-lock/package-lock.json"
@@ -115,52 +126,57 @@ func TestParsePackageLockV2(t *testing.T) {
var expectedRelationships []artifact.Relationship var expectedRelationships []artifact.Relationship
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "npm", Name: "npm",
Version: "6.14.6", Version: "6.14.6",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/npm@6.14.6", Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{}, PURL: "pkg:npm/npm@6.14.6",
Metadata: pkg.NpmPackageLockEntry{},
}, },
{ {
Name: "@types/prop-types", Name: "@types/prop-types",
Version: "15.7.5", Version: "15.7.5",
PURL: "pkg:npm/%40types/prop-types@15.7.5", PURL: "pkg:npm/%40types/prop-types@15.7.5",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="}, Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha1-XxnSuFqY6VWANvajysyIGUIPBc8="},
}, },
{ {
Name: "@types/react", Name: "@types/react",
Version: "18.0.17", Version: "18.0.17",
PURL: "pkg:npm/%40types/react@18.0.17", PURL: "pkg:npm/%40types/react@18.0.17",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", Integrity: "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ="}, Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.17.tgz", Integrity: "sha1-RYPZwyLWfv5LOak10iPtzHBQzPQ="},
}, },
{ {
Name: "@types/scheduler", Name: "@types/scheduler",
Version: "0.16.2", Version: "0.16.2",
PURL: "pkg:npm/%40types/scheduler@0.16.2", PURL: "pkg:npm/%40types/scheduler@0.16.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="}, Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk="},
}, },
{ {
Name: "csstype", Name: "csstype",
Version: "3.1.0", Version: "3.1.0",
PURL: "pkg:npm/csstype@3.1.0", PURL: "pkg:npm/csstype@3.1.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
@@ -179,44 +195,49 @@ func TestParsePackageLockV3(t *testing.T) {
var expectedRelationships []artifact.Relationship var expectedRelationships []artifact.Relationship
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "lock-v3-fixture", Name: "lock-v3-fixture",
Version: "1.0.0", Version: "1.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/lock-v3-fixture@1.0.0", Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{}, PURL: "pkg:npm/lock-v3-fixture@1.0.0",
Metadata: pkg.NpmPackageLockEntry{},
}, },
{ {
Name: "@types/prop-types", Name: "@types/prop-types",
Version: "15.7.5", Version: "15.7.5",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/%40types/prop-types@15.7.5", Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="}, PURL: "pkg:npm/%40types/prop-types@15.7.5",
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", Integrity: "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="},
}, },
{ {
Name: "@types/react", Name: "@types/react",
Version: "18.0.20", Version: "18.0.20",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/%40types/react@18.0.20", Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", Integrity: "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA=="}, PURL: "pkg:npm/%40types/react@18.0.20",
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/react/-/react-18.0.20.tgz", Integrity: "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA=="},
}, },
{ {
Name: "@types/scheduler", Name: "@types/scheduler",
Version: "0.16.2", Version: "0.16.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/%40types/scheduler@0.16.2", Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="}, PURL: "pkg:npm/%40types/scheduler@0.16.2",
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", Integrity: "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="},
}, },
{ {
Name: "csstype", Name: "csstype",
Version: "3.1.1", Version: "3.1.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
PURL: "pkg:npm/csstype@3.1.1", PURL: "pkg:npm/csstype@3.1.1",
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", Integrity: "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", Integrity: "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="},
}, },
} }
for i := range expectedPkgs { for i := range expectedPkgs {
@@ -230,28 +251,31 @@ func TestParsePackageLockAlias(t *testing.T) {
var expectedRelationships []artifact.Relationship var expectedRelationships []artifact.Relationship
commonPkgs := []pkg.Package{ commonPkgs := []pkg.Package{
{ {
Name: "case", Name: "case",
Version: "1.6.2", Version: "1.6.2",
PURL: "pkg:npm/case@1.6.2", PURL: "pkg:npm/case@1.6.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.2.tgz", Integrity: "sha512-ll380ZRoraT7mUK2G92UbH+FJVD5AwdVIAYk9xhV1tauh0carDgYByUD1HhjCWsWgxrfQvCeHvtfj7IYR6TKeg=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.2.tgz", Integrity: "sha512-ll380ZRoraT7mUK2G92UbH+FJVD5AwdVIAYk9xhV1tauh0carDgYByUD1HhjCWsWgxrfQvCeHvtfj7IYR6TKeg=="},
}, },
{ {
Name: "case", Name: "case",
Version: "1.6.3", Version: "1.6.3",
PURL: "pkg:npm/case@1.6.3", PURL: "pkg:npm/case@1.6.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.3.tgz", Integrity: "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/case/-/case-1.6.3.tgz", Integrity: "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ=="},
}, },
{ {
Name: "@bundled-es-modules/chai", Name: "@bundled-es-modules/chai",
Version: "4.2.2", Version: "4.2.2",
PURL: "pkg:npm/%40bundled-es-modules/chai@4.2.2", PURL: "pkg:npm/%40bundled-es-modules/chai@4.2.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@bundled-es-modules/chai/-/chai-4.2.2.tgz", Integrity: "sha512-iGmVYw2/zJCoqyKTtWEYCtFmMyi8WmACQKtky0lpNyEKWX0YIOpKWGD7saMXL+tPpllss0otilxV0SLwyi3Ytg=="}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/@bundled-es-modules/chai/-/chai-4.2.2.tgz", Integrity: "sha512-iGmVYw2/zJCoqyKTtWEYCtFmMyi8WmACQKtky0lpNyEKWX0YIOpKWGD7saMXL+tPpllss0otilxV0SLwyi3Ytg=="},
}, },
} }
@@ -268,7 +292,8 @@ func TestParsePackageLockAlias(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("ISC", file.NewLocation(packageLockV2)), pkg.NewLicenseFromLocations("ISC", file.NewLocation(packageLockV2)),
), ),
Metadata: pkg.NpmPackageLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NpmPackageLockEntry{},
} }
for _, pl := range packageLocks { for _, pl := range packageLocks {
@@ -292,10 +317,11 @@ func TestParsePackageLockLicenseWithArray(t *testing.T) {
var expectedRelationships []artifact.Relationship var expectedRelationships []artifact.Relationship
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "tmp", Name: "tmp",
Version: "1.0.0", Version: "1.0.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("ISC", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("ISC", file.NewLocation(fixture)),
), ),
@@ -303,11 +329,11 @@ func TestParsePackageLockLicenseWithArray(t *testing.T) {
Metadata: pkg.NpmPackageLockEntry{}, Metadata: pkg.NpmPackageLockEntry{},
}, },
{ {
Name: "pause-stream", Name: "pause-stream",
Version: "0.0.11", Version: "0.0.11",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
pkg.NewLicenseFromLocations("Apache2", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("Apache2", file.NewLocation(fixture)),
@@ -316,10 +342,11 @@ func TestParsePackageLockLicenseWithArray(t *testing.T) {
Metadata: pkg.NpmPackageLockEntry{}, Metadata: pkg.NpmPackageLockEntry{},
}, },
{ {
Name: "through", Name: "through",
Version: "2.3.8", Version: "2.3.8",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
@@ -17,36 +17,40 @@ func TestParsePnpmLock(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "nanoid", Name: "nanoid",
Version: "3.3.4", Version: "3.3.4",
PURL: "pkg:npm/nanoid@3.3.4", PURL: "pkg:npm/nanoid@3.3.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "picocolors", Name: "picocolors",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:npm/picocolors@1.0.0", PURL: "pkg:npm/picocolors@1.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "source-map-js", Name: "source-map-js",
Version: "1.0.2", Version: "1.0.2",
PURL: "pkg:npm/source-map-js@1.0.2", PURL: "pkg:npm/source-map-js@1.0.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "@bcoe/v8-coverage", Name: "@bcoe/v8-coverage",
Version: "0.2.3", Version: "0.2.3",
PURL: "pkg:npm/%40bcoe/v8-coverage@0.2.3", PURL: "pkg:npm/%40bcoe/v8-coverage@0.2.3",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
} }
@@ -61,84 +65,94 @@ func TestParsePnpmV6Lock(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "@testing-library/jest-dom", Name: "@testing-library/jest-dom",
Version: "5.16.5", Version: "5.16.5",
PURL: "pkg:npm/%40testing-library/jest-dom@5.16.5", PURL: "pkg:npm/%40testing-library/jest-dom@5.16.5",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "@testing-library/react", Name: "@testing-library/react",
Version: "13.4.0", Version: "13.4.0",
PURL: "pkg:npm/%40testing-library/react@13.4.0", PURL: "pkg:npm/%40testing-library/react@13.4.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "@testing-library/user-event", Name: "@testing-library/user-event",
Version: "13.5.0", Version: "13.5.0",
PURL: "pkg:npm/%40testing-library/user-event@13.5.0", PURL: "pkg:npm/%40testing-library/user-event@13.5.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "react", Name: "react",
Version: "18.2.0", Version: "18.2.0",
PURL: "pkg:npm/react@18.2.0", PURL: "pkg:npm/react@18.2.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "react-dom", Name: "react-dom",
Version: "18.2.0", Version: "18.2.0",
PURL: "pkg:npm/react-dom@18.2.0", PURL: "pkg:npm/react-dom@18.2.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "web-vitals", Name: "web-vitals",
Version: "2.1.4", Version: "2.1.4",
PURL: "pkg:npm/web-vitals@2.1.4", PURL: "pkg:npm/web-vitals@2.1.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "@babel/core", Name: "@babel/core",
Version: "7.21.4", Version: "7.21.4",
PURL: "pkg:npm/%40babel/core@7.21.4", PURL: "pkg:npm/%40babel/core@7.21.4",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "@types/eslint", Name: "@types/eslint",
Version: "8.37.0", Version: "8.37.0",
PURL: "pkg:npm/%40types/eslint@8.37.0", PURL: "pkg:npm/%40types/eslint@8.37.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "read-cache", Name: "read-cache",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:npm/read-cache@1.0.0", PURL: "pkg:npm/read-cache@1.0.0",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "schema-utils", Name: "schema-utils",
Version: "3.1.2", Version: "3.1.2",
PURL: "pkg:npm/schema-utils@3.1.2", PURL: "pkg:npm/schema-utils@3.1.2",
Locations: locationSet, Locations: locationSet,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
} }
@@ -22,85 +22,94 @@ func TestParseYarnBerry(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "@babel/code-frame", Name: "@babel/code-frame",
Version: "7.10.4", Version: "7.10.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40babel/code-frame@7.10.4", PURL: "pkg:npm/%40babel/code-frame@7.10.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "@types/minimatch", Name: "@types/minimatch",
Version: "3.0.3", Version: "3.0.3",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40types/minimatch@3.0.3", PURL: "pkg:npm/%40types/minimatch@3.0.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "@types/qs", Name: "@types/qs",
Version: "6.9.4", Version: "6.9.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40types/qs@6.9.4", PURL: "pkg:npm/%40types/qs@6.9.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "ajv", Name: "ajv",
Version: "6.12.3", Version: "6.12.3",
Locations: locations, Locations: locations,
PURL: "pkg:npm/ajv@6.12.3", PURL: "pkg:npm/ajv@6.12.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "asn1.js", Name: "asn1.js",
Version: "4.10.1", Version: "4.10.1",
Locations: locations, Locations: locations,
PURL: "pkg:npm/asn1.js@4.10.1", PURL: "pkg:npm/asn1.js@4.10.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "atob", Name: "atob",
Version: "2.1.2", Version: "2.1.2",
Locations: locations, Locations: locations,
PURL: "pkg:npm/atob@2.1.2", PURL: "pkg:npm/atob@2.1.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "aws-sdk", Name: "aws-sdk",
Version: "2.706.0", Version: "2.706.0",
PURL: "pkg:npm/aws-sdk@2.706.0", PURL: "pkg:npm/aws-sdk@2.706.0",
Locations: locations, Locations: locations,
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "c0n-fab_u.laTION", Name: "c0n-fab_u.laTION",
Version: "7.7.7", Version: "7.7.7",
Locations: locations, Locations: locations,
PURL: "pkg:npm/c0n-fab_u.laTION@7.7.7", PURL: "pkg:npm/c0n-fab_u.laTION@7.7.7",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
{ {
Name: "jhipster-core", Name: "jhipster-core",
Version: "7.3.4", Version: "7.3.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/jhipster-core@7.3.4", PURL: "pkg:npm/jhipster-core@7.3.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Metadata: pkg.YarnLockEntry{}, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{},
}, },
} }
@@ -115,60 +124,65 @@ func TestParseYarnLock(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "@babel/code-frame", Name: "@babel/code-frame",
Version: "7.10.4", Version: "7.10.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40babel/code-frame@7.10.4", PURL: "pkg:npm/%40babel/code-frame@7.10.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a", Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a",
Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
}, },
}, },
{ {
Name: "@types/minimatch", Name: "@types/minimatch",
Version: "3.0.3", Version: "3.0.3",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40types/minimatch@3.0.3", PURL: "pkg:npm/%40types/minimatch@3.0.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d", Resolved: "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d",
Integrity: "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", Integrity: "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
}, },
}, },
{ {
Name: "@types/qs", Name: "@types/qs",
Version: "6.9.4", Version: "6.9.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40types/qs@6.9.4", PURL: "pkg:npm/%40types/qs@6.9.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a", Resolved: "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a",
Integrity: "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==", Integrity: "sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ==",
}, },
}, },
{ {
Name: "ajv", Name: "ajv",
Version: "6.12.3", Version: "6.12.3",
Locations: locations, Locations: locations,
PURL: "pkg:npm/ajv@6.12.3", PURL: "pkg:npm/ajv@6.12.3",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706", Resolved: "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706",
Integrity: "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", Integrity: "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
}, },
}, },
{ {
Name: "asn1.js", Name: "asn1.js",
Version: "4.10.1", Version: "4.10.1",
Locations: locations, Locations: locations,
PURL: "pkg:npm/asn1.js@4.10.1", PURL: "pkg:npm/asn1.js@4.10.1",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0", Resolved: "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0",
Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
@@ -179,45 +193,49 @@ func TestParseYarnLock(t *testing.T) {
Version: "2.1.2", Version: "2.1.2",
Locations: locations, Locations: locations,
PURL: "pkg:npm/atob@2.1.2", PURL: "pkg:npm/atob@2.1.2",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9", Resolved: "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9",
Integrity: "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", Integrity: "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
}, },
}, },
{ {
Name: "aws-sdk", Name: "aws-sdk",
Version: "2.706.0", Version: "2.706.0",
Locations: locations, Locations: locations,
PURL: "pkg:npm/aws-sdk@2.706.0", PURL: "pkg:npm/aws-sdk@2.706.0",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953", Resolved: "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.706.0.tgz#09f65e9a91ecac5a635daf934082abae30eca953",
Integrity: "sha512-7GT+yrB5Wb/zOReRdv/Pzkb2Qt+hz6B/8FGMVaoysX3NryHvQUdz7EQWi5yhg9CxOjKxdw5lFwYSs69YlSp1KA==", Integrity: "sha512-7GT+yrB5Wb/zOReRdv/Pzkb2Qt+hz6B/8FGMVaoysX3NryHvQUdz7EQWi5yhg9CxOjKxdw5lFwYSs69YlSp1KA==",
}, },
}, },
{ {
Name: "jhipster-core", Name: "jhipster-core",
Version: "7.3.4", Version: "7.3.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/jhipster-core@7.3.4", PURL: "pkg:npm/jhipster-core@7.3.4",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-7.3.4.tgz#c34b8c97c7f4e8b7518dae015517e2112c73cc80", Resolved: "https://registry.yarnpkg.com/jhipster-core/-/jhipster-core-7.3.4.tgz#c34b8c97c7f4e8b7518dae015517e2112c73cc80",
Integrity: "sha512-AUhT69kNkqppaJZVfan/xnKG4Gs9Ggj7YLtTZFVe+xg+THrbMb5Ng7PL07PDlDw4KAEA33GMCwuAf65E8EpC4g==", Integrity: "sha512-AUhT69kNkqppaJZVfan/xnKG4Gs9Ggj7YLtTZFVe+xg+THrbMb5Ng7PL07PDlDw4KAEA33GMCwuAf65E8EpC4g==",
}, },
}, },
{ {
Name: "something-i-made-up", Name: "something-i-made-up",
Version: "7.7.7", Version: "7.7.7",
Locations: locations, Locations: locations,
PURL: "pkg:npm/something-i-made-up@7.7.7", PURL: "pkg:npm/something-i-made-up@7.7.7",
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/something-i-made-up/-/c0n-fab_u.laTION-7.7.7.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0", Resolved: "https://registry.yarnpkg.com/something-i-made-up/-/c0n-fab_u.laTION-7.7.7.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0",
Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", Integrity: "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
@@ -258,13 +276,14 @@ func TestSearchYarnForLicenses(t *testing.T) {
}, },
expectedPackages: []pkg.Package{ expectedPackages: []pkg.Package{
{ {
Name: "@babel/code-frame", Name: "@babel/code-frame",
Version: "7.10.4", Version: "7.10.4",
Locations: locations, Locations: locations,
PURL: "pkg:npm/%40babel/code-frame@7.10.4", PURL: "pkg:npm/%40babel/code-frame@7.10.4",
Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")), Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
Language: pkg.JavaScript, Language: pkg.JavaScript,
Type: pkg.NpmPkg, Type: pkg.NpmPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.YarnLockEntry{ Metadata: pkg.YarnLockEntry{
Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a", Resolved: "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a",
Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", Integrity: "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
+7 -5
View File
@@ -21,9 +21,10 @@ func Test_KernelCataloger(t *testing.T) {
"/lib/modules/6.0.7-301.fc37.x86_64/vmlinuz", "/lib/modules/6.0.7-301.fc37.x86_64/vmlinuz",
), ),
), ),
Type: pkg.LinuxKernelPkg, Type: pkg.LinuxKernelPkg,
PURL: "pkg:generic/linux-kernel@6.0.7-301.fc37.x86_64", PURL: "pkg:generic/linux-kernel@6.0.7-301.fc37.x86_64",
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:o:linux:linux_kernel:6.0.7-301.fc37.x86_64:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource)}, CPEs: []cpe.CPE{cpe.Must("cpe:2.3:o:linux:linux_kernel:6.0.7-301.fc37.x86_64:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource)},
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LinuxKernel{ Metadata: pkg.LinuxKernel{
Name: "", Name: "",
Architecture: "x86", Architecture: "x86",
@@ -56,8 +57,9 @@ func Test_KernelCataloger(t *testing.T) {
), ),
), ),
), ),
Type: pkg.LinuxKernelModulePkg, Type: pkg.LinuxKernelModulePkg,
PURL: "pkg:generic/ttynull", PURL: "pkg:generic/ttynull",
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LinuxKernelModule{ Metadata: pkg.LinuxKernelModule{
Name: "ttynull", Name: "ttynull",
Version: "", Version: "",
+16 -14
View File
@@ -26,13 +26,14 @@ func createLinuxKernelCPEs(version string) []cpe.CPE {
func newLinuxKernelPackage(metadata pkg.LinuxKernel, archiveLocation file.Location) pkg.Package { func newLinuxKernelPackage(metadata pkg.LinuxKernel, archiveLocation file.Location) pkg.Package {
p := pkg.Package{ p := pkg.Package{
Name: linuxKernelPackageName, Name: linuxKernelPackageName,
Version: metadata.Version, Version: metadata.Version,
Locations: file.NewLocationSet(archiveLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(archiveLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
PURL: packageURL(linuxKernelPackageName, metadata.Version), PURL: packageURL(linuxKernelPackageName, metadata.Version),
Type: pkg.LinuxKernelPkg, Type: pkg.LinuxKernelPkg,
Metadata: metadata, Metadata: metadata,
CPEs: createLinuxKernelCPEs(metadata.Version), Dependencies: pkg.UnknownDependencyCompleteness,
CPEs: createLinuxKernelCPEs(metadata.Version),
} }
p.SetID() p.SetID()
@@ -42,13 +43,14 @@ func newLinuxKernelPackage(metadata pkg.LinuxKernel, archiveLocation file.Locati
func newLinuxKernelModulePackage(metadata pkg.LinuxKernelModule, kmLocation file.Location) pkg.Package { func newLinuxKernelModulePackage(metadata pkg.LinuxKernelModule, kmLocation file.Location) pkg.Package {
p := pkg.Package{ p := pkg.Package{
Name: metadata.Name, Name: metadata.Name,
Version: metadata.Version, Version: metadata.Version,
Locations: file.NewLocationSet(kmLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(kmLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(kmLocation, metadata.License)...), Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(kmLocation, metadata.License)...),
PURL: packageURL(metadata.Name, metadata.Version), PURL: packageURL(metadata.Name, metadata.Version),
Type: pkg.LinuxKernelModulePkg, Type: pkg.LinuxKernelModulePkg,
Metadata: metadata, Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: metadata,
} }
p.SetID() p.SetID()
+2
View File
@@ -16,6 +16,8 @@ func newLuaRocksPackage(u luaRocksPackage, indexLocation file.Location) pkg.Pack
Language: pkg.Lua, Language: pkg.Lua,
Licenses: pkg.NewLicenseSet(license...), Licenses: pkg.NewLicenseSet(license...),
Type: pkg.LuaRocksPkg, Type: pkg.LuaRocksPkg,
// no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LuaRocksPackage{ Metadata: pkg.LuaRocksPackage{
Name: u.Name, Name: u.Name,
Version: u.Version, Version: u.Version,
@@ -24,6 +24,7 @@ func TestParseRockspec(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Apache-2.0", file.NewLocation("test-fixtures/rockspec/kong-3.7.0-0.rockspec")), pkg.NewLicenseFromLocations("Apache-2.0", file.NewLocation("test-fixtures/rockspec/kong-3.7.0-0.rockspec")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LuaRocksPackage{ Metadata: pkg.LuaRocksPackage{
Name: "kong", Name: "kong",
Version: "3.7.0-0", Version: "3.7.0-0",
@@ -45,6 +46,7 @@ func TestParseRockspec(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT/X11", file.NewLocation("test-fixtures/rockspec/lpeg-1.0.2-1.rockspec")), pkg.NewLicenseFromLocations("MIT/X11", file.NewLocation("test-fixtures/rockspec/lpeg-1.0.2-1.rockspec")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LuaRocksPackage{ Metadata: pkg.LuaRocksPackage{
Name: "LPeg", Name: "LPeg",
Version: "1.0.2-1", Version: "1.0.2-1",
@@ -66,6 +68,7 @@ func TestParseRockspec(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/rockspec/kong-pgmoon-1.16.2-1.rockspec")), pkg.NewLicenseFromLocations("MIT", file.NewLocation("test-fixtures/rockspec/kong-pgmoon-1.16.2-1.rockspec")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LuaRocksPackage{ Metadata: pkg.LuaRocksPackage{
Name: "kong-pgmoon", Name: "kong-pgmoon",
Version: "1.16.2-1", Version: "1.16.2-1",
@@ -87,6 +90,7 @@ func TestParseRockspec(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT/X11", file.NewLocation("test-fixtures/rockspec/luasyslog-2.0.1-1.rockspec")), pkg.NewLicenseFromLocations("MIT/X11", file.NewLocation("test-fixtures/rockspec/luasyslog-2.0.1-1.rockspec")),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.LuaRocksPackage{ Metadata: pkg.LuaRocksPackage{
Name: "luasyslog", Name: "luasyslog",
Version: "2.0.1-1", Version: "2.0.1-1",
+7 -6
View File
@@ -20,12 +20,13 @@ func TestCataloger_Catalog(t *testing.T) {
fixture: "test-fixtures/fixture-1", fixture: "test-fixtures/fixture-1",
wantPkgs: []pkg.Package{ wantPkgs: []pkg.Package{
{ {
Name: "glibc", Name: "glibc",
Version: "2.34-210", Version: "2.34-210",
PURL: "pkg:nix/glibc@2.34-210?output=bin&outputhash=h0cnbmfcn93xm5dg2x27ixhag1cwndga", PURL: "pkg:nix/glibc@2.34-210?output=bin&outputhash=h0cnbmfcn93xm5dg2x27ixhag1cwndga",
Locations: file.NewLocationSet(file.NewLocation("nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin")), Locations: file.NewLocationSet(file.NewLocation("nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin")),
FoundBy: catalogerName, FoundBy: catalogerName,
Type: pkg.NixPkg, Type: pkg.NixPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NixStoreEntry{ Metadata: pkg.NixStoreEntry{
OutputHash: "h0cnbmfcn93xm5dg2x27ixhag1cwndga", OutputHash: "h0cnbmfcn93xm5dg2x27ixhag1cwndga",
Output: "bin", Output: "bin",
+2
View File
@@ -14,6 +14,8 @@ func newNixStorePackage(storePath nixStorePath, locations ...file.Location) pkg.
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
Type: pkg.NixPkg, Type: pkg.NixPkg,
PURL: packageURL(storePath), PURL: packageURL(storePath),
// no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.NixStoreEntry{ Metadata: pkg.NixStoreEntry{
OutputHash: storePath.outputHash, OutputHash: storePath.outputHash,
Output: storePath.output, Output: storePath.output,
+3 -1
View File
@@ -15,7 +15,9 @@ func newOpamPackage(m pkg.OpamPackage, fileLocation file.Location) pkg.Package {
Locations: file.NewLocationSet(fileLocation), Locations: file.NewLocationSet(fileLocation),
Type: pkg.OpamPkg, Type: pkg.OpamPkg,
Language: pkg.OCaml, Language: pkg.OCaml,
Metadata: m, // no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: m,
} }
p.SetID() p.SetID()
+6 -4
View File
@@ -36,8 +36,9 @@ func TestParseOpamPackage(t *testing.T) {
"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception", "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception",
)..., )...,
), ),
Language: pkg.OCaml, Language: pkg.OCaml,
Type: pkg.OpamPkg, Type: pkg.OpamPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.OpamPackage{ Metadata: pkg.OpamPackage{
Name: "ocaml-base-compiler", Name: "ocaml-base-compiler",
Version: "4.14.0", Version: "4.14.0",
@@ -65,8 +66,9 @@ func TestParseOpamPackage(t *testing.T) {
"ISC", "ISC",
)..., )...,
), ),
Language: pkg.OCaml, Language: pkg.OCaml,
Type: pkg.OpamPkg, Type: pkg.OpamPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.OpamPackage{ Metadata: pkg.OpamPackage{
Name: "alcotest", Name: "alcotest",
Version: "1.5.0", Version: "1.5.0",
+9 -3
View File
@@ -17,7 +17,9 @@ func newComposerLockPackage(pd parsedLockData, indexLocation file.Location) pkg.
PURL: packageURL(pd.Name, pd.Version), PURL: packageURL(pd.Name, pd.Version),
Language: pkg.PHP, Language: pkg.PHP,
Type: pkg.PhpComposerPkg, Type: pkg.PhpComposerPkg,
Metadata: pd.PhpComposerLockEntry, // no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pd.PhpComposerLockEntry,
} }
p.SetID() p.SetID()
@@ -33,7 +35,9 @@ func newComposerInstalledPackage(pd parsedInstalledData, indexLocation file.Loca
PURL: packageURL(pd.Name, pd.Version), PURL: packageURL(pd.Name, pd.Version),
Language: pkg.PHP, Language: pkg.PHP,
Type: pkg.PhpComposerPkg, Type: pkg.PhpComposerPkg,
Metadata: pd.PhpComposerInstalledEntry, // no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pd.PhpComposerInstalledEntry,
} }
p.SetID() p.SetID()
@@ -49,7 +53,9 @@ func newPeclPackage(pd pkg.PhpPeclEntry, indexLocation file.Location) pkg.Packag
PURL: packageURLFromPecl(pd.Name, pd.Version), PURL: packageURLFromPecl(pd.Name, pd.Version),
Language: pkg.PHP, Language: pkg.PHP,
Type: pkg.PhpPeclPkg, Type: pkg.PhpPeclPkg,
Metadata: pd, // no attempt is made by the parser function to raise up dependency relationships
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pd,
} }
p.SetID() p.SetID()
@@ -22,8 +22,9 @@ func TestParseComposerFileLock(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
Language: pkg.PHP, Language: pkg.PHP,
Type: pkg.PhpComposerPkg, Type: pkg.PhpComposerPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PhpComposerLockEntry{ Metadata: pkg.PhpComposerLockEntry{
Name: "adoy/fastcgi-client", Name: "adoy/fastcgi-client",
Version: "1.0.2", Version: "1.0.2",
@@ -62,7 +63,8 @@ func TestParseComposerFileLock(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("MIT", file.NewLocation(fixture)),
), ),
Type: pkg.PhpComposerPkg, Type: pkg.PhpComposerPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PhpComposerLockEntry{ Metadata: pkg.PhpComposerLockEntry{
Name: "alcaeus/mongo-php-adapter", Name: "alcaeus/mongo-php-adapter",
Version: "1.1.11", Version: "1.1.11",
@@ -26,6 +26,7 @@ func TestParseInstalledJsonComposerV1(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT"), pkg.NewLicense("MIT"),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PhpComposerInstalledEntry{ Metadata: pkg.PhpComposerInstalledEntry{
Name: "asm89/stack-cors", Name: "asm89/stack-cors",
Version: "1.3.0", Version: "1.3.0",
@@ -75,6 +76,7 @@ func TestParseInstalledJsonComposerV1(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicense("MIT"), pkg.NewLicense("MIT"),
), ),
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PhpComposerInstalledEntry{ Metadata: pkg.PhpComposerInstalledEntry{
Name: "behat/mink", Name: "behat/mink",
Version: "v1.8.1", Version: "v1.8.1",
@@ -22,8 +22,9 @@ func TestParsePeclSerialized(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("PHP License", file.NewLocation(fixture)), pkg.NewLicenseFromLocations("PHP License", file.NewLocation(fixture)),
), ),
Language: pkg.PHP, Language: pkg.PHP,
Type: pkg.PhpPeclPkg, Type: pkg.PhpPeclPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PhpPeclEntry{ Metadata: pkg.PhpPeclEntry{
Name: "memcached", Name: "memcached",
Version: "3.2.0", Version: "3.2.0",
+32 -13
View File
@@ -8,6 +8,7 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/anchore/syft/internal/licenses"
"github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
@@ -23,11 +24,12 @@ func Test_PackageCataloger(t *testing.T) {
name: "egg-file-no-version", name: "egg-file-no-version",
fixtures: []string{"test-fixtures/no-version-py3.8.egg-info"}, fixtures: []string{"test-fixtures/no-version-py3.8.egg-info"},
expectedPackage: pkg.Package{ expectedPackage: pkg.Package{
Name: "no-version", Name: "no-version",
PURL: "pkg:pypi/no-version", PURL: "pkg:pypi/no-version",
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Language: pkg.Python, Language: pkg.Python,
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "no-version", Name: "no-version",
SitePackagesRootPath: "test-fixtures", SitePackagesRootPath: "test-fixtures",
@@ -50,7 +52,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/egg-info/PKG-INFO")), pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/egg-info/PKG-INFO")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "requests", Name: "requests",
Version: "2.22.0", Version: "2.22.0",
@@ -88,7 +91,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/casesensitive/EGG-INFO/PKG-INFO")), pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/casesensitive/EGG-INFO/PKG-INFO")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "requests", Name: "requests",
Version: "2.22.0", Version: "2.22.0",
@@ -127,7 +131,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/dist-info/METADATA")), pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/dist-info/METADATA")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "Pygments", Name: "Pygments",
Version: "2.6.1", Version: "2.6.1",
@@ -169,7 +174,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/casesensitive/DIST-INFO/METADATA")), pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/casesensitive/DIST-INFO/METADATA")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "Pygments", Name: "Pygments",
Version: "2.6.1", Version: "2.6.1",
@@ -207,7 +213,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/malformed-record/dist-info/METADATA")), pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/malformed-record/dist-info/METADATA")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "Pygments", Name: "Pygments",
Version: "2.6.1", Version: "2.6.1",
@@ -239,7 +246,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/partial.dist-info/METADATA")), pkg.NewLicenseFromLocations("BSD License", file.NewLocation("test-fixtures/partial.dist-info/METADATA")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "Pygments", Name: "Pygments",
Version: "2.6.1", Version: "2.6.1",
@@ -263,7 +271,8 @@ func Test_PackageCataloger(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/test.egg-info")), pkg.NewLicenseFromLocations("Apache 2.0", file.NewLocation("test-fixtures/test.egg-info")),
), ),
FoundBy: "python-installed-package-cataloger", FoundBy: "python-installed-package-cataloger",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPackage{ Metadata: pkg.PythonPackage{
Name: "requests", Name: "requests",
Version: "2.22.0", Version: "2.22.0",
@@ -278,6 +287,8 @@ func Test_PackageCataloger(t *testing.T) {
}, },
} }
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.NewDefaultScanner())
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
resolver := file.NewMockResolverForPaths(test.fixtures...) resolver := file.NewMockResolverForPaths(test.fixtures...)
@@ -289,6 +300,7 @@ func Test_PackageCataloger(t *testing.T) {
pkgtest.NewCatalogTester(). pkgtest.NewCatalogTester().
WithResolver(resolver). WithResolver(resolver).
WithContext(ctx).
Expects([]pkg.Package{test.expectedPackage}, nil). Expects([]pkg.Package{test.expectedPackage}, nil).
TestCataloger(t, NewInstalledPackageCataloger()) TestCataloger(t, NewInstalledPackageCataloger())
}) })
@@ -296,6 +308,8 @@ func Test_PackageCataloger(t *testing.T) {
} }
func Test_PackageCataloger_IgnorePackage(t *testing.T) { func Test_PackageCataloger_IgnorePackage(t *testing.T) {
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.NewDefaultScanner())
tests := []struct { tests := []struct {
MetadataFixture string MetadataFixture string
}{ }{
@@ -311,7 +325,7 @@ func Test_PackageCataloger_IgnorePackage(t *testing.T) {
t.Run(test.MetadataFixture, func(t *testing.T) { t.Run(test.MetadataFixture, func(t *testing.T) {
resolver := file.NewMockResolverForPaths(test.MetadataFixture) resolver := file.NewMockResolverForPaths(test.MetadataFixture)
actual, _, err := NewInstalledPackageCataloger().Catalog(context.Background(), resolver) actual, _, err := NewInstalledPackageCataloger().Catalog(ctx, resolver)
require.NoError(t, err) require.NoError(t, err)
if len(actual) != 0 { if len(actual) != 0 {
@@ -353,6 +367,7 @@ func Test_IndexCataloger_Globs(t *testing.T) {
} }
func Test_PackageCataloger_Globs(t *testing.T) { func Test_PackageCataloger_Globs(t *testing.T) {
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.NewDefaultScanner())
tests := []struct { tests := []struct {
name string name string
fixture string fixture string
@@ -375,6 +390,7 @@ func Test_PackageCataloger_Globs(t *testing.T) {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
pkgtest.NewCatalogTester(). pkgtest.NewCatalogTester().
FromDirectory(t, test.fixture). FromDirectory(t, test.fixture).
WithContext(ctx).
ExpectsResolverContentQueries(test.expected). ExpectsResolverContentQueries(test.expected).
IgnoreUnfulfilledPathResponses("**/pyvenv.cfg"). IgnoreUnfulfilledPathResponses("**/pyvenv.cfg").
TestCataloger(t, NewInstalledPackageCataloger()) TestCataloger(t, NewInstalledPackageCataloger())
@@ -670,10 +686,13 @@ func Test_PackageCataloger_SitePackageRelationships(t *testing.T) {
}, },
} }
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.NewDefaultScanner())
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
pkgtest.NewCatalogTester(). pkgtest.NewCatalogTester().
WithImageResolver(t, test.fixture). WithImageResolver(t, test.fixture).
WithContext(ctx).
WithPackageStringer(stringPackage). WithPackageStringer(stringPackage).
ExpectsRelationshipStrings(test.expectedRelationships). ExpectsRelationshipStrings(test.expectedRelationships).
TestCataloger(t, NewInstalledPackageCataloger()) TestCataloger(t, NewInstalledPackageCataloger())
+36 -32
View File
@@ -20,16 +20,17 @@ func normalize(name string) string {
return strings.ToLower(normalized) return strings.ToLower(normalized)
} }
func newPackageForIndex(name, version string, locations ...file.Location) pkg.Package { func newPackageForIndex(name, version string, dep pkg.DependencyCompleteness, locations ...file.Location) pkg.Package {
name = normalize(name) name = normalize(name)
p := pkg.Package{ p := pkg.Package{
Name: name, Name: name,
Version: version, Version: version,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(name, version, nil), PURL: packageURL(name, version, nil),
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: dep,
} }
p.SetID() p.SetID()
@@ -37,17 +38,18 @@ func newPackageForIndex(name, version string, locations ...file.Location) pkg.Pa
return p return p
} }
func newPackageForIndexWithMetadata(name, version string, metadata interface{}, locations ...file.Location) pkg.Package { func newPackageForIndexWithMetadata(name, version string, metadata interface{}, dep pkg.DependencyCompleteness, locations ...file.Location) pkg.Package {
name = normalize(name) name = normalize(name)
p := pkg.Package{ p := pkg.Package{
Name: name, Name: name,
Version: version, Version: version,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(name, version, nil), PURL: packageURL(name, version, nil),
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: metadata, Dependencies: dep,
Metadata: metadata,
} }
p.SetID() p.SetID()
@@ -55,17 +57,18 @@ func newPackageForIndexWithMetadata(name, version string, metadata interface{},
return p return p
} }
func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, locations ...file.Location) pkg.Package { func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, dep pkg.DependencyCompleteness, locations ...file.Location) pkg.Package {
name = normalize(name) name = normalize(name)
p := pkg.Package{ p := pkg.Package{
Name: name, Name: name,
Version: version, Version: version,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
PURL: packageURL(name, version, nil), PURL: packageURL(name, version, nil),
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: metadata, Dependencies: dep,
Metadata: metadata,
} }
p.SetID() p.SetID()
@@ -73,18 +76,19 @@ func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.Py
return p return p
} }
func newPackageForPackage(m parsedData, licenses pkg.LicenseSet, sources ...file.Location) pkg.Package { func newPackageForPackage(m parsedData, licenses pkg.LicenseSet, dep pkg.DependencyCompleteness, sources ...file.Location) pkg.Package {
name := normalize(m.Name) name := normalize(m.Name)
p := pkg.Package{ p := pkg.Package{
Name: name, Name: name,
Version: m.Version, Version: m.Version,
PURL: packageURL(name, m.Version, &m.PythonPackage), PURL: packageURL(name, m.Version, &m.PythonPackage),
Locations: file.NewLocationSet(sources...), Locations: file.NewLocationSet(sources...),
Licenses: licenses, Licenses: licenses,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: m.PythonPackage, Dependencies: dep,
Metadata: m.PythonPackage,
} }
p.SetID() p.SetID()
@@ -66,7 +66,13 @@ func parsePipfileLock(_ context.Context, _ file.Resolver, _ *generic.Environment
index = "https://pypi.org/simple" index = "https://pypi.org/simple"
} }
version := strings.TrimPrefix(pkgMeta.Version, "==") version := strings.TrimPrefix(pkgMeta.Version, "==")
pkgs = append(pkgs, newPackageForIndexWithMetadata(name, version, pkg.PythonPipfileLockEntry{Index: index, Hashes: pkgMeta.Hashes}, reader.Location)) pkgs = append(pkgs, newPackageForIndexWithMetadata(
name,
version,
pkg.PythonPipfileLockEntry{Index: index, Hashes: pkgMeta.Hashes},
pkg.UnknownDependencyCompleteness, // no attempt is made to resolve dependencies from the lock file
reader.Location,
))
} }
} }
@@ -15,12 +15,13 @@ func TestParsePipFileLock(t *testing.T) {
locations := file.NewLocationSet(file.NewLocation(fixture)) locations := file.NewLocationSet(file.NewLocation(fixture))
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "aio-pika", Name: "aio-pika",
Version: "6.8.0", Version: "6.8.0",
PURL: "pkg:pypi/aio-pika@6.8.0", PURL: "pkg:pypi/aio-pika@6.8.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonPipfileLockEntry{ Metadata: pkg.PythonPipfileLockEntry{
Index: "https://pypi.org/simple", Index: "https://pypi.org/simple",
Hashes: []string{ Hashes: []string{
@@ -29,12 +30,13 @@ func TestParsePipFileLock(t *testing.T) {
}}, }},
}, },
{ {
Name: "aiodns", Name: "aiodns",
Version: "2.0.0", Version: "2.0.0",
PURL: "pkg:pypi/aiodns@2.0.0", PURL: "pkg:pypi/aiodns@2.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonPipfileLockEntry{ Metadata: pkg.PythonPipfileLockEntry{
Index: "https://test.pypi.org/simple", Index: "https://test.pypi.org/simple",
Hashes: []string{ Hashes: []string{
@@ -44,12 +46,13 @@ func TestParsePipFileLock(t *testing.T) {
}, },
}, },
{ {
Name: "aiohttp", Name: "aiohttp",
Version: "3.7.4.post0", Version: "3.7.4.post0",
PURL: "pkg:pypi/aiohttp@3.7.4.post0", PURL: "pkg:pypi/aiohttp@3.7.4.post0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonPipfileLockEntry{ Metadata: pkg.PythonPipfileLockEntry{
Index: "https://pypi.org/simple", Index: "https://pypi.org/simple",
Hashes: []string{ Hashes: []string{
@@ -59,12 +62,13 @@ func TestParsePipFileLock(t *testing.T) {
}, },
}, },
{ {
Name: "aiohttp-jinja2", Name: "aiohttp-jinja2",
Version: "1.4.2", Version: "1.4.2",
PURL: "pkg:pypi/aiohttp-jinja2@1.4.2", PURL: "pkg:pypi/aiohttp-jinja2@1.4.2",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonPipfileLockEntry{ Metadata: pkg.PythonPipfileLockEntry{
Index: "https://pypi.org/simple", Index: "https://pypi.org/simple",
Hashes: []string{ Hashes: []string{
@@ -99,6 +99,7 @@ func poetryLockPackages(reader file.LocationReadCloser) ([]pkg.Package, error) {
p.Name, p.Name,
p.Version, p.Version,
newPythonPoetryLockEntry(p), newPythonPoetryLockEntry(p),
pkg.CompleteDependencies,
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
) )
@@ -14,12 +14,13 @@ func TestParsePoetryLock(t *testing.T) {
locations := file.NewLocationSet(file.NewLocation(fixture)) locations := file.NewLocationSet(file.NewLocation(fixture))
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "added-value", Name: "added-value",
Version: "0.14.2", Version: "0.14.2",
PURL: "pkg:pypi/added-value@0.14.2", PURL: "pkg:pypi/added-value@0.14.2",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPoetryLockEntry{ Metadata: pkg.PythonPoetryLockEntry{
Index: "https://test.pypi.org/simple", Index: "https://test.pypi.org/simple",
Dependencies: []pkg.PythonPoetryLockDependencyEntry{ Dependencies: []pkg.PythonPoetryLockDependencyEntry{
@@ -49,31 +50,34 @@ func TestParsePoetryLock(t *testing.T) {
}, },
}, },
{ {
Name: "alabaster", Name: "alabaster",
Version: "0.7.12", Version: "0.7.12",
PURL: "pkg:pypi/alabaster@0.7.12", PURL: "pkg:pypi/alabaster@0.7.12",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"}, Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
}, },
{ {
Name: "appnope", Name: "appnope",
Version: "0.1.0", Version: "0.1.0",
PURL: "pkg:pypi/appnope@0.1.0", PURL: "pkg:pypi/appnope@0.1.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"}, Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
}, },
{ {
Name: "asciitree", Name: "asciitree",
Version: "0.3.3", Version: "0.3.3",
PURL: "pkg:pypi/asciitree@0.3.3", PURL: "pkg:pypi/asciitree@0.3.3",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"}, Dependencies: pkg.CompleteDependencies,
Metadata: pkg.PythonPoetryLockEntry{Index: "https://pypi.org/simple"},
}, },
} }
@@ -153,6 +153,7 @@ func (rp requirementsParser) parseRequirementsTxt(_ context.Context, _ file.Reso
URL: parseURL(req.URL), URL: parseURL(req.URL),
Markers: req.Markers, Markers: req.Markers,
}, },
pkg.UnknownDependencyCompleteness, // not attempt is made by the parser function to resolve dependencies
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
) )
@@ -17,36 +17,39 @@ func TestParseRequirementsTxt(t *testing.T) {
pinnedPkgs := []pkg.Package{ pinnedPkgs := []pkg.Package{
{ {
Name: "flask", Name: "flask",
Version: "4.0.0", Version: "4.0.0",
PURL: "pkg:pypi/flask@4.0.0", PURL: "pkg:pypi/flask@4.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "flask", Name: "flask",
VersionConstraint: "== 4.0.0", VersionConstraint: "== 4.0.0",
}, },
}, },
{ {
Name: "foo", Name: "foo",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:pypi/foo@1.0.0", PURL: "pkg:pypi/foo@1.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "foo", Name: "foo",
VersionConstraint: "== 1.0.0", VersionConstraint: "== 1.0.0",
}, },
}, },
{ {
Name: "someproject", Name: "someproject",
Version: "5.4", Version: "5.4",
PURL: "pkg:pypi/someproject@5.4", PURL: "pkg:pypi/someproject@5.4",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "SomeProject", Name: "SomeProject",
VersionConstraint: "==5.4", VersionConstraint: "==5.4",
@@ -54,48 +57,52 @@ func TestParseRequirementsTxt(t *testing.T) {
}, },
}, },
{ {
Name: "dots-allowed", Name: "dots-allowed",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:pypi/dots-allowed@1.0.0", PURL: "pkg:pypi/dots-allowed@1.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "dots-._allowed", Name: "dots-._allowed",
VersionConstraint: "== 1.0.0", VersionConstraint: "== 1.0.0",
}, },
}, },
{ {
Name: "argh", Name: "argh",
Version: "0.26.2", Version: "0.26.2",
PURL: "pkg:pypi/argh@0.26.2", PURL: "pkg:pypi/argh@0.26.2",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "argh", Name: "argh",
VersionConstraint: "==0.26.2", VersionConstraint: "==0.26.2",
}, },
}, },
{ {
Name: "argh", Name: "argh",
Version: "0.26.3", Version: "0.26.3",
PURL: "pkg:pypi/argh@0.26.3", PURL: "pkg:pypi/argh@0.26.3",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "argh", Name: "argh",
VersionConstraint: "==0.26.3", VersionConstraint: "==0.26.3",
}, },
}, },
{ {
Name: "celery", Name: "celery",
Version: "4.4.7", Version: "4.4.7",
PURL: "pkg:pypi/celery@4.4.7", PURL: "pkg:pypi/celery@4.4.7",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "celery", Name: "celery",
Extras: []string{"redis", "pytest"}, Extras: []string{"redis", "pytest"},
@@ -103,12 +110,13 @@ func TestParseRequirementsTxt(t *testing.T) {
}, },
}, },
{ {
Name: "githubsampleproject", Name: "githubsampleproject",
Version: "3.7.1", Version: "3.7.1",
PURL: "pkg:pypi/githubsampleproject@3.7.1", PURL: "pkg:pypi/githubsampleproject@3.7.1",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "GithubSampleProject", Name: "GithubSampleProject",
VersionConstraint: "== 3.7.1", VersionConstraint: "== 3.7.1",
@@ -116,12 +124,13 @@ func TestParseRequirementsTxt(t *testing.T) {
}, },
}, },
{ {
Name: "friendly-bard", Name: "friendly-bard",
Version: "1.0.0", Version: "1.0.0",
PURL: "pkg:pypi/friendly-bard@1.0.0", PURL: "pkg:pypi/friendly-bard@1.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "FrIeNdLy-_-bArD", Name: "FrIeNdLy-_-bArD",
VersionConstraint: "== 1.0.0", VersionConstraint: "== 1.0.0",
@@ -152,48 +161,52 @@ func TestParseRequirementsTxt(t *testing.T) {
}, },
expectedPkgs: append([]pkg.Package{ expectedPkgs: append([]pkg.Package{
{ {
Name: "mopidy-dirble", Name: "mopidy-dirble",
Version: "1.1", Version: "1.1",
PURL: "pkg:pypi/mopidy-dirble@1.1", PURL: "pkg:pypi/mopidy-dirble@1.1",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "Mopidy-Dirble", Name: "Mopidy-Dirble",
VersionConstraint: "~= 1.1", VersionConstraint: "~= 1.1",
}, },
}, },
{ {
Name: "sqlalchemy", Name: "sqlalchemy",
Version: "2.0.0", Version: "2.0.0",
PURL: "pkg:pypi/sqlalchemy@2.0.0", PURL: "pkg:pypi/sqlalchemy@2.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "sqlalchemy", Name: "sqlalchemy",
VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0", VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0",
}, },
}, },
{ {
Name: "bar", Name: "bar",
Version: "2.0.0", Version: "2.0.0",
PURL: "pkg:pypi/bar@2.0.0", PURL: "pkg:pypi/bar@2.0.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "bar", Name: "bar",
VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0", VersionConstraint: ">= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0",
}, },
}, },
{ {
Name: "numpy", Name: "numpy",
Version: "3.4.1", Version: "3.4.1",
PURL: "pkg:pypi/numpy@3.4.1", PURL: "pkg:pypi/numpy@3.4.1",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "numpy", Name: "numpy",
VersionConstraint: ">= 3.4.1", VersionConstraint: ">= 3.4.1",
@@ -201,12 +214,13 @@ func TestParseRequirementsTxt(t *testing.T) {
}, },
}, },
{ {
Name: "requests", Name: "requests",
Version: "2.8.0", Version: "2.8.0",
PURL: "pkg:pypi/requests@2.8.0", PURL: "pkg:pypi/requests@2.8.0",
Locations: locations, Locations: locations,
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pkg.PythonRequirementsEntry{ Metadata: pkg.PythonRequirementsEntry{
Name: "requests", Name: "requests",
Extras: []string{"security"}, Extras: []string{"security"},
+1
View File
@@ -59,6 +59,7 @@ func parseSetup(_ context.Context, _ file.Resolver, _ *generic.Environment, read
newPackageForIndex( newPackageForIndex(
name, name,
version, version,
pkg.UnknownDependencyCompleteness, // no attempt is made by the parser function to resolve dependencies
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
), ),
) )
+30 -25
View File
@@ -20,39 +20,44 @@ func TestParseSetup(t *testing.T) {
fixture: "test-fixtures/setup/setup.py", fixture: "test-fixtures/setup/setup.py",
expected: []pkg.Package{ expected: []pkg.Package{
{ {
Name: "pathlib3", Name: "pathlib3",
Version: "2.2.0", Version: "2.2.0",
PURL: "pkg:pypi/pathlib3@2.2.0", PURL: "pkg:pypi/pathlib3@2.2.0",
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "mypy", Name: "mypy",
Version: "v0.770", Version: "v0.770",
PURL: "pkg:pypi/mypy@v0.770", PURL: "pkg:pypi/mypy@v0.770",
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "mypy1", Name: "mypy1",
Version: "v0.770", Version: "v0.770",
PURL: "pkg:pypi/mypy1@v0.770", PURL: "pkg:pypi/mypy1@v0.770",
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "mypy2", Name: "mypy2",
Version: "v0.770", Version: "v0.770",
PURL: "pkg:pypi/mypy2@v0.770", PURL: "pkg:pypi/mypy2@v0.770",
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
{ {
Name: "mypy3", Name: "mypy3",
Version: "v0.770", Version: "v0.770",
PURL: "pkg:pypi/mypy3@v0.770", PURL: "pkg:pypi/mypy3@v0.770",
Language: pkg.Python, Language: pkg.Python,
Type: pkg.PythonPkg, Type: pkg.PythonPkg,
Dependencies: pkg.UnknownDependencyCompleteness,
}, },
}, },
}, },
@@ -40,6 +40,7 @@ func parseWheelOrEgg(ctx context.Context, resolver file.Resolver, _ *generic.Env
newPackageForPackage( newPackageForPackage(
*pd, *pd,
findLicenses(ctx, licenseScanner, resolver, *pd), findLicenses(ctx, licenseScanner, resolver, *pd),
pkg.CompleteDependencies,
sources..., sources...,
), ),
} }
+18 -16
View File
@@ -12,14 +12,15 @@ import (
func TestRPackageCataloger(t *testing.T) { func TestRPackageCataloger(t *testing.T) {
expectedPkgs := []pkg.Package{ expectedPkgs := []pkg.Package{
{ {
Name: "base", Name: "base",
Version: "4.3.0", Version: "4.3.0",
FoundBy: "r-package-cataloger", FoundBy: "r-package-cataloger",
Locations: file.NewLocationSet(file.NewLocation("base/DESCRIPTION")), Locations: file.NewLocationSet(file.NewLocation("base/DESCRIPTION")),
Licenses: pkg.NewLicenseSet([]pkg.License{pkg.NewLicense("Part of R 4.3.0")}...), Licenses: pkg.NewLicenseSet([]pkg.License{pkg.NewLicense("Part of R 4.3.0")}...),
Language: pkg.R, Language: pkg.R,
Type: pkg.Rpkg, Type: pkg.Rpkg,
PURL: "pkg:cran/base@4.3.0", Dependencies: pkg.UnknownDependencyCompleteness,
PURL: "pkg:cran/base@4.3.0",
Metadata: pkg.RDescription{ Metadata: pkg.RDescription{
Title: "The R Base Package", Title: "The R Base Package",
Description: "Base R functions.", Description: "Base R functions.",
@@ -30,14 +31,15 @@ func TestRPackageCataloger(t *testing.T) {
}, },
}, },
{ {
Name: "stringr", Name: "stringr",
Version: "1.5.0.9000", Version: "1.5.0.9000",
FoundBy: "r-package-cataloger", FoundBy: "r-package-cataloger",
Locations: file.NewLocationSet(file.NewLocation("stringr/DESCRIPTION")), Locations: file.NewLocationSet(file.NewLocation("stringr/DESCRIPTION")),
Licenses: pkg.NewLicenseSet([]pkg.License{pkg.NewLicense("MIT")}...), Licenses: pkg.NewLicenseSet([]pkg.License{pkg.NewLicense("MIT")}...),
Language: pkg.R, Language: pkg.R,
Type: pkg.Rpkg, Type: pkg.Rpkg,
PURL: "pkg:cran/stringr@1.5.0.9000", Dependencies: pkg.UnknownDependencyCompleteness,
PURL: "pkg:cran/stringr@1.5.0.9000",
Metadata: pkg.RDescription{ Metadata: pkg.RDescription{
Title: "Simple, Consistent Wrappers for Common String Operations", Title: "Simple, Consistent Wrappers for Common String Operations",
Description: "A consistent, simple and easy to use set of wrappers around the fantastic 'stringi' package. All function and argument names (and positions) are consistent, all functions deal with \"NA\"'s and zero length vectors in the same way, and the output from one function is easy to feed into the input of another.", Description: "A consistent, simple and easy to use set of wrappers around the fantastic 'stringi' package. All function and argument names (and positions) are consistent, all functions deal with \"NA\"'s and zero length vectors in the same way, and the output from one function is easy to feed into the input of another.",
+3 -1
View File
@@ -24,7 +24,9 @@ func newPackage(pd parseData, locations ...file.Location) pkg.Package {
Language: pkg.R, Language: pkg.R,
Type: pkg.Rpkg, Type: pkg.Rpkg,
PURL: packageURL(pd), PURL: packageURL(pd),
Metadata: pd.RDescription, // no attempt is made by the parser function to resolve dependencies
Dependencies: pkg.UnknownDependencyCompleteness,
Metadata: pd.RDescription,
} }
result.SetID() result.SetID()
+24 -21
View File
@@ -20,13 +20,14 @@ func Test_DBCataloger(t *testing.T) {
locations := file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)) locations := file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
basePkg := pkg.Package{ basePkg := pkg.Package{
Name: "basesystem", Name: "basesystem",
Version: "11-13.el9", Version: "11-13.el9",
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Locations: locations, Locations: locations,
Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("Public Domain", dbLocation)), Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("Public Domain", dbLocation)),
FoundBy: "rpm-db-cataloger", FoundBy: "rpm-db-cataloger",
PURL: "pkg:rpm/basesystem@11-13.el9?arch=noarch&upstream=basesystem-11-13.el9.src.rpm", PURL: "pkg:rpm/basesystem@11-13.el9?arch=noarch&upstream=basesystem-11-13.el9.src.rpm",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.RpmDBEntry{ Metadata: pkg.RpmDBEntry{
Name: "basesystem", Name: "basesystem",
Version: "11", Version: "11",
@@ -50,13 +51,14 @@ func Test_DBCataloger(t *testing.T) {
basePkg.SetID() basePkg.SetID()
bashPkg := pkg.Package{ bashPkg := pkg.Package{
Name: "bash", Name: "bash",
Version: "5.1.8-6.el9_1", Version: "5.1.8-6.el9_1",
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Locations: locations, Locations: locations,
Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("GPLv3+", dbLocation)), Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("GPLv3+", dbLocation)),
FoundBy: "rpm-db-cataloger", FoundBy: "rpm-db-cataloger",
PURL: "pkg:rpm/bash@5.1.8-6.el9_1?arch=x86_64&upstream=bash-5.1.8-6.el9_1.src.rpm", PURL: "pkg:rpm/bash@5.1.8-6.el9_1?arch=x86_64&upstream=bash-5.1.8-6.el9_1.src.rpm",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.RpmDBEntry{ Metadata: pkg.RpmDBEntry{
Name: "bash", Name: "bash",
Version: "5.1.8", Version: "5.1.8",
@@ -102,13 +104,14 @@ func Test_DBCataloger(t *testing.T) {
bashPkg.SetID() bashPkg.SetID()
filesystemPkg := pkg.Package{ filesystemPkg := pkg.Package{
Name: "filesystem", Name: "filesystem",
Version: "3.16-2.el9", Version: "3.16-2.el9",
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Locations: locations, Locations: locations,
Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("Public Domain", dbLocation)), Licenses: pkg.NewLicenseSet(pkg.NewLicenseFromLocations("Public Domain", dbLocation)),
FoundBy: "rpm-db-cataloger", FoundBy: "rpm-db-cataloger",
PURL: "pkg:rpm/filesystem@3.16-2.el9?arch=x86_64&upstream=filesystem-3.16-2.el9.src.rpm", PURL: "pkg:rpm/filesystem@3.16-2.el9?arch=x86_64&upstream=filesystem-3.16-2.el9.src.rpm",
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.RpmDBEntry{ Metadata: pkg.RpmDBEntry{
Name: "filesystem", Name: "filesystem",
Version: "3.16", Version: "3.16",
+9 -8
View File
@@ -11,15 +11,16 @@ import (
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
) )
func newDBPackage(dbOrRpmLocation file.Location, m pkg.RpmDBEntry, distro *linux.Release, licenses []string) pkg.Package { func newDBPackage(dbOrRpmLocation file.Location, m pkg.RpmDBEntry, distro *linux.Release, licenses []string, deps pkg.DependencyCompleteness) pkg.Package {
p := pkg.Package{ p := pkg.Package{
Name: m.Name, Name: m.Name,
Version: toELVersion(m.Epoch, m.Version, m.Release), Version: toELVersion(m.Epoch, m.Version, m.Release),
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbOrRpmLocation, licenses...)...), Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbOrRpmLocation, licenses...)...),
PURL: packageURL(m.Name, m.Arch, m.Epoch, m.SourceRpm, m.Version, m.Release, distro), PURL: packageURL(m.Name, m.Arch, m.Epoch, m.SourceRpm, m.Version, m.Release, distro),
Locations: file.NewLocationSet(dbOrRpmLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Locations: file.NewLocationSet(dbOrRpmLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
Type: pkg.RpmPkg, Type: pkg.RpmPkg,
Metadata: m, Dependencies: deps,
Metadata: m,
} }
p.SetID() p.SetID()
@@ -89,6 +89,7 @@ func parseRpmDB(_ context.Context, resolver file.Resolver, env *generic.Environm
metadata, metadata,
distro, distro,
[]string{entry.License}, []string{entry.License},
pkg.CompleteDependencies,
) )
if !pkg.IsValid(&p) { if !pkg.IsValid(&p) {
@@ -100,6 +100,7 @@ func TestParseRpmDB(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", packagesLocation), pkg.NewLicenseFromLocations("MIT", packagesLocation),
), ),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.RpmDBEntry{ Metadata: pkg.RpmDBEntry{
Name: "dive", Name: "dive",
Epoch: nil, Epoch: nil,
@@ -130,6 +131,7 @@ func TestParseRpmDB(t *testing.T) {
Licenses: pkg.NewLicenseSet( Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", packagesLocation), pkg.NewLicenseFromLocations("MIT", packagesLocation),
), ),
Dependencies: pkg.CompleteDependencies,
Metadata: pkg.RpmDBEntry{ Metadata: pkg.RpmDBEntry{
Name: "dive", Name: "dive",
Epoch: nil, Epoch: nil,
@@ -44,7 +44,10 @@ func parseRpmManifest(_ context.Context, _ file.Resolver, _ *generic.Environment
continue continue
} }
p := newDBPackage(reader.Location, *metadata, nil, nil) // Create a new package representing the RPM manifest entry
// note: we don't know the quality of the manifest dependency information, so even though there are multiple
// packages, we can't discern the connectivity of completeness of the data.
p := newDBPackage(reader.Location, *metadata, nil, nil, pkg.UnknownDependencyCompleteness)
if !pkg.IsValid(&p) { if !pkg.IsValid(&p) {
continue continue

Some files were not shown because too many files have changed in this diff Show More