mirror of
https://github.com/anchore/syft.git
synced 2026-11-05 00:46:38 +01:00
Deduplicate packages across multiple container image layers (#930)
This commit is contained in:
@@ -16,7 +16,7 @@ func Test_disallowJenkinsServerCPEForPluginPackage(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "go case (filter out)",
|
||||
cpe: mustCPE("cpe:2.3:a:name:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:name:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Type: pkg.JenkinsPluginPkg,
|
||||
},
|
||||
@@ -24,7 +24,7 @@ func Test_disallowJenkinsServerCPEForPluginPackage(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore jenkins plugins with unique name",
|
||||
cpe: mustCPE("cpe:2.3:a:name:ci-jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:name:ci-jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Type: pkg.JenkinsPluginPkg,
|
||||
},
|
||||
@@ -32,7 +32,7 @@ func Test_disallowJenkinsServerCPEForPluginPackage(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore java packages",
|
||||
cpe: mustCPE("cpe:2.3:a:name:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:name:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Type: pkg.JavaPkg,
|
||||
},
|
||||
@@ -55,7 +55,7 @@ func Test_disallowJenkinsCPEsNotAssociatedWithJenkins(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "filter out mismatched name (cloudbees vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:cloudbees:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:cloudbees:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "not-j*nkins",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -64,7 +64,7 @@ func Test_disallowJenkinsCPEsNotAssociatedWithJenkins(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "filter out mismatched name (jenkins vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:jenkins:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:jenkins:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "not-j*nkins",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -73,7 +73,7 @@ func Test_disallowJenkinsCPEsNotAssociatedWithJenkins(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "filter out mismatched name (any vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "not-j*nkins",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -82,7 +82,7 @@ func Test_disallowJenkinsCPEsNotAssociatedWithJenkins(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore packages with the name jenkins",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jenkins:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "jenkins-thing",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -91,7 +91,7 @@ func Test_disallowJenkinsCPEsNotAssociatedWithJenkins(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore product names that are not exactly 'jenkins'",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jenkins-something-else:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jenkins-something-else:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "not-j*nkins",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -115,7 +115,7 @@ func Test_disallowJiraClientServerMismatch(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "filter out mismatched name (atlassian vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:atlassian:jira:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:atlassian:jira:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "something-client",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -124,7 +124,7 @@ func Test_disallowJiraClientServerMismatch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "filter out mismatched name (jira vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:jira:jira:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:jira:jira:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "something-client",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -133,7 +133,7 @@ func Test_disallowJiraClientServerMismatch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "filter out mismatched name (any vendor)",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jira:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jira:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "something-client",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -142,7 +142,7 @@ func Test_disallowJiraClientServerMismatch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore package names that do not have 'client'",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jira:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jira:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "jira-thing",
|
||||
Type: pkg.JavaPkg,
|
||||
@@ -151,7 +151,7 @@ func Test_disallowJiraClientServerMismatch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ignore product names that are not exactly 'jira'",
|
||||
cpe: mustCPE("cpe:2.3:a:*:jira-something-else:3.2:*:*:*:*:*:*:*"),
|
||||
cpe: pkg.MustCPE("cpe:2.3:a:*:jira-something-else:3.2:*:*:*:*:*:*:*"),
|
||||
pkg: pkg.Package{
|
||||
Name: "not-j*ra",
|
||||
Type: pkg.JavaPkg,
|
||||
|
||||
@@ -55,7 +55,7 @@ func Generate(p pkg.Package) []pkg.CPE {
|
||||
// filter out any known combinations that don't accurately represent this package
|
||||
cpes = filter(cpes, p, cpeFilters...)
|
||||
|
||||
sort.Sort(BySpecificity(cpes))
|
||||
sort.Sort(pkg.CPEBySpecificity(cpes))
|
||||
|
||||
return cpes
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
package cpe
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/facebookincubator/nvdtools/wfn"
|
||||
)
|
||||
|
||||
var _ sort.Interface = (*BySpecificity)(nil)
|
||||
|
||||
type BySpecificity []wfn.Attributes
|
||||
|
||||
func (c BySpecificity) Len() int { return len(c) }
|
||||
|
||||
func (c BySpecificity) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
|
||||
|
||||
func (c BySpecificity) Less(i, j int) bool {
|
||||
iScore := weightedCountForSpecifiedFields(c[i])
|
||||
jScore := weightedCountForSpecifiedFields(c[j])
|
||||
|
||||
// check weighted sort first
|
||||
if iScore != jScore {
|
||||
return iScore > jScore
|
||||
}
|
||||
|
||||
// sort longer fields to top
|
||||
if countFieldLength(c[i]) != countFieldLength(c[j]) {
|
||||
return countFieldLength(c[i]) > countFieldLength(c[j])
|
||||
}
|
||||
|
||||
// if score and length are equal then text sort
|
||||
// note that we are not using CPEString from the syft pkg
|
||||
// as we are not encoding/decoding this CPE string so we don't
|
||||
// need the proper quoted version of the CPE.
|
||||
return c[i].BindToFmtString() < c[j].BindToFmtString()
|
||||
}
|
||||
|
||||
func countFieldLength(cpe wfn.Attributes) int {
|
||||
return len(cpe.Part + cpe.Vendor + cpe.Product + cpe.Version + cpe.TargetSW)
|
||||
}
|
||||
|
||||
func weightedCountForSpecifiedFields(cpe wfn.Attributes) int {
|
||||
checksForSpecifiedField := []func(cpe wfn.Attributes) (bool, int){
|
||||
func(cpe wfn.Attributes) (bool, int) { return cpe.Part != "", 2 },
|
||||
func(cpe wfn.Attributes) (bool, int) { return cpe.Vendor != "", 3 },
|
||||
func(cpe wfn.Attributes) (bool, int) { return cpe.Product != "", 4 },
|
||||
func(cpe wfn.Attributes) (bool, int) { return cpe.Version != "", 1 },
|
||||
func(cpe wfn.Attributes) (bool, int) { return cpe.TargetSW != "", 1 },
|
||||
}
|
||||
|
||||
weightedCount := 0
|
||||
for _, fieldIsSpecified := range checksForSpecifiedField {
|
||||
isSpecified, weight := fieldIsSpecified(cpe)
|
||||
if isSpecified {
|
||||
weightedCount += weight
|
||||
}
|
||||
}
|
||||
|
||||
return weightedCount
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package cpe
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func mustCPE(c string) pkg.CPE {
|
||||
return must(pkg.NewCPE(c))
|
||||
}
|
||||
|
||||
func must(c pkg.CPE, e error) pkg.CPE {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func TestCPESpecificity(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input []pkg.CPE
|
||||
expected []pkg.CPE
|
||||
}{
|
||||
{
|
||||
name: "sort strictly by wfn *",
|
||||
input: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:*:package:1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:some:package:1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:*:package:1:*:*:*:*:some:*:*"),
|
||||
mustCPE("cpe:2.3:a:some:package:1:*:*:*:*:some:*:*"),
|
||||
mustCPE("cpe:2.3:a:some:package:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
expected: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:some:package:1:*:*:*:*:some:*:*"),
|
||||
mustCPE("cpe:2.3:a:some:package:1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:some:package:*:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:*:package:1:*:*:*:*:some:*:*"),
|
||||
mustCPE("cpe:2.3:a:*:package:1:*:*:*:*:*:*:*"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sort strictly by field length",
|
||||
input: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:1:22:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:55555:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:333:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:666666:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:4444:*:*"),
|
||||
},
|
||||
expected: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:1:666666:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:55555:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:4444:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:333:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:22:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:1:*:*"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sort by mix of field length and specificity",
|
||||
input: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:1:666666:*:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:*:1:1:*:*:*:*:4444:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:*:333:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:22:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:55555:1:1:*:*:*:*:1:*:*"),
|
||||
},
|
||||
expected: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:55555:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:22:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:1:1:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:666666:*:*:*:*:*:1:*:*"),
|
||||
mustCPE("cpe:2.3:a:*:1:1:*:*:*:*:4444:*:*"),
|
||||
mustCPE("cpe:2.3:a:1:*:333:*:*:*:*:*:*:*"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sort by mix of field length, specificity, dash",
|
||||
input: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:alpine:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine_keys:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine-keys:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine-keys:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine_keys:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
},
|
||||
expected: []pkg.CPE{
|
||||
mustCPE("cpe:2.3:a:alpine-keys:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine-keys:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine_keys:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine_keys:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine:alpine-keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
mustCPE("cpe:2.3:a:alpine:alpine_keys:2.3-r1:*:*:*:*:*:*:*"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sort.Sort(BySpecificity(test.input))
|
||||
assert.Equal(t, test.expected, test.input)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -58,9 +58,8 @@ func (c *GenericCataloger) Catalog(resolver source.FileResolver) ([]pkg.Package,
|
||||
|
||||
for _, p := range discoveredPackages {
|
||||
p.FoundBy = c.upstreamCataloger
|
||||
p.Locations = append(p.Locations, location)
|
||||
p.Locations.Add(location)
|
||||
p.SetID()
|
||||
|
||||
packages = append(packages, *p)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ func TestGenericCataloger(t *testing.T) {
|
||||
assert.Len(t, actualPkgs, len(expectedPkgs))
|
||||
|
||||
for _, p := range actualPkgs {
|
||||
ref := p.Locations[0]
|
||||
ref := p.Locations.ToSlice()[0]
|
||||
exP, ok := expectedPkgs[ref.RealPath]
|
||||
if !ok {
|
||||
t.Errorf("missing expected pkg: ref=%+v", ref)
|
||||
|
||||
@@ -60,7 +60,7 @@ func (c *Cataloger) Catalog(resolver source.FileResolver) ([]pkg.Package, []arti
|
||||
for i := range pkgs {
|
||||
p := &pkgs[i]
|
||||
p.FoundBy = c.Name()
|
||||
p.Locations = []source.Location{dbLocation}
|
||||
p.Locations.Add(dbLocation)
|
||||
|
||||
// the current entry only has what may have been listed in the status file, however, there are additional
|
||||
// files that are listed in multiple other locations. We should retrieve them all and merge the file lists
|
||||
@@ -88,7 +88,7 @@ func addLicenses(resolver source.FileResolver, dbLocation source.Location, p *pk
|
||||
p.Licenses = parseLicensesFromCopyright(copyrightReader)
|
||||
|
||||
// keep a record of the file where this was discovered
|
||||
p.Locations = append(p.Locations, *copyrightLocation)
|
||||
p.Locations.Add(*copyrightLocation)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ loopNewFiles:
|
||||
p.Metadata = metadata
|
||||
|
||||
// persist location information from each new source of information
|
||||
p.Locations = append(p.Locations, infoLocations...)
|
||||
p.Locations.Add(infoLocations...)
|
||||
}
|
||||
|
||||
func getAdditionalFileListing(resolver source.FileResolver, dbLocation source.Location, p *pkg.Package) ([]pkg.DpkgFileRecord, []source.Location) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package deb
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -115,15 +116,13 @@ func TestDpkgCataloger(t *testing.T) {
|
||||
for idx := range actual {
|
||||
a := &actual[idx]
|
||||
// we will test the sources separately
|
||||
var sourcesList = make([]string, len(a.Locations))
|
||||
for i, s := range a.Locations {
|
||||
var sourcesList = make([]string, len(a.Locations.ToSlice()))
|
||||
for i, s := range a.Locations.ToSlice() {
|
||||
sourcesList[i] = s.RealPath
|
||||
}
|
||||
a.Locations = nil
|
||||
a.Locations = source.NewLocationSet()
|
||||
|
||||
for _, d := range deep.Equal(sourcesList, test.sources[a.Name]) {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
assert.ElementsMatch(t, sourcesList, test.sources[a.Name])
|
||||
}
|
||||
|
||||
// test remaining fields...
|
||||
|
||||
@@ -44,14 +44,12 @@ func newGoBinaryPackage(dep *debug.Module, goVersion, architecture string, locat
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
FoundBy: catalogerName,
|
||||
Name: dep.Path,
|
||||
Version: dep.Version,
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
location,
|
||||
},
|
||||
FoundBy: catalogerName,
|
||||
Name: dep.Path,
|
||||
Version: dep.Version,
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: source.NewLocationSet(location),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goVersion,
|
||||
|
||||
@@ -133,14 +133,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
FoundBy: catalogerName,
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
@@ -190,14 +190,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
Version: "v0.2.1",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
@@ -252,14 +252,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
Version: "v0.2.1",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
@@ -273,14 +273,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
Version: "v0.0.0-20210222170800-9c70f9b80bcf",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
@@ -327,12 +327,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
Version: "v0.0.0-20211006194710-c8a6f5223071",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
}}},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
@@ -344,14 +346,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
Version: "v0.0.0-20210916214954-140adaaadfaf",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: []source.Location{
|
||||
{
|
||||
Locations: source.NewLocationSet(
|
||||
source.Location{
|
||||
Coordinates: source.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
),
|
||||
MetadataType: pkg.GolangBinMetadataType,
|
||||
Metadata: pkg.GolangBinMetadata{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
|
||||
@@ -80,7 +80,7 @@ func (c *PackageCataloger) catalogEggOrWheel(resolver source.FileResolver, metad
|
||||
Name: metadata.Name,
|
||||
Version: metadata.Version,
|
||||
FoundBy: c.Name(),
|
||||
Locations: sources,
|
||||
Locations: source.NewLocationSet(sources...),
|
||||
Licenses: licenses,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
|
||||
@@ -144,7 +144,7 @@ func TestPythonPackageWheelCataloger(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
test.expectedPackage.Locations = locations
|
||||
test.expectedPackage.Locations = source.NewLocationSet(locations...)
|
||||
|
||||
actual, _, err := NewPythonPackageCataloger().Catalog(resolver)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package python
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -48,7 +49,14 @@ func TestParsePipFileLock(t *testing.T) {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(expected, actual, cmp.AllowUnexported(pkg.Package{})); diff != "" {
|
||||
if diff := cmp.Diff(expected, actual,
|
||||
cmp.AllowUnexported(pkg.Package{}),
|
||||
cmp.Comparer(
|
||||
func(x, y source.LocationSet) bool {
|
||||
return cmp.Equal(x.ToSlice(), y.ToSlice())
|
||||
},
|
||||
),
|
||||
); diff != "" {
|
||||
t.Errorf("unexpected result from parsing (-expected +actual)\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package python
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -42,7 +43,14 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(expected, actual, cmp.AllowUnexported(pkg.Package{})); diff != "" {
|
||||
if diff := cmp.Diff(expected, actual,
|
||||
cmp.AllowUnexported(pkg.Package{}),
|
||||
cmp.Comparer(
|
||||
func(x, y source.LocationSet) bool {
|
||||
return cmp.Equal(x.ToSlice(), y.ToSlice())
|
||||
},
|
||||
),
|
||||
); diff != "" {
|
||||
t.Errorf("unexpected result from parsing (-expected +actual)\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package python
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -54,7 +55,14 @@ func TestParseSetup(t *testing.T) {
|
||||
t.Fatalf("failed to parse requirements: %+v", err)
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(expected, actual, cmp.AllowUnexported(pkg.Package{})); diff != "" {
|
||||
if diff := cmp.Diff(expected, actual,
|
||||
cmp.AllowUnexported(pkg.Package{}),
|
||||
cmp.Comparer(
|
||||
func(x, y source.LocationSet) bool {
|
||||
return cmp.Equal(x.ToSlice(), y.ToSlice())
|
||||
},
|
||||
),
|
||||
); diff != "" {
|
||||
t.Errorf("unexpected result from parsing (-expected +actual)\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func parseRpmDB(resolver source.FilePathResolver, dbLocation source.Location, re
|
||||
p := pkg.Package{
|
||||
Name: entry.Name,
|
||||
Version: toELVersion(metadata),
|
||||
Locations: []source.Location{dbLocation},
|
||||
Locations: source.NewLocationSet(dbLocation),
|
||||
FoundBy: catalogerName,
|
||||
Type: pkg.RpmPkg,
|
||||
MetadataType: pkg.RpmdbMetadataType,
|
||||
|
||||
@@ -71,7 +71,7 @@ func TestParseRpmDB(t *testing.T) {
|
||||
"dive": {
|
||||
Name: "dive",
|
||||
Version: "0.9.2-1",
|
||||
Locations: []source.Location{dbLocation},
|
||||
Locations: source.NewLocationSet(dbLocation),
|
||||
FoundBy: catalogerName,
|
||||
Type: pkg.RpmPkg,
|
||||
MetadataType: pkg.RpmdbMetadataType,
|
||||
@@ -98,7 +98,7 @@ func TestParseRpmDB(t *testing.T) {
|
||||
"dive": {
|
||||
Name: "dive",
|
||||
Version: "0.9.2-1",
|
||||
Locations: []source.Location{dbLocation},
|
||||
Locations: source.NewLocationSet(dbLocation),
|
||||
FoundBy: catalogerName,
|
||||
Type: pkg.RpmPkg,
|
||||
MetadataType: pkg.RpmdbMetadataType,
|
||||
|
||||
Reference in New Issue
Block a user