mirror of
https://github.com/anchore/syft.git
synced 2026-02-14 03:26:41 +01:00
rename pkg.Catalog to pkg.Collection (#1764)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
02bd52728e
commit
fd02bef0a3
@ -54,7 +54,7 @@ func ToSyftModel(bom *cyclonedx.BOM) (*sbom.SBOM, error) {
|
|||||||
|
|
||||||
s := &sbom.SBOM{
|
s := &sbom.SBOM{
|
||||||
Artifacts: sbom.Artifacts{
|
Artifacts: sbom.Artifacts{
|
||||||
PackageCatalog: pkg.NewCatalog(),
|
PackageCatalog: pkg.NewCollection(),
|
||||||
LinuxDistribution: linuxReleaseFromComponents(*bom.Components),
|
LinuxDistribution: linuxReleaseFromComponents(*bom.Components),
|
||||||
},
|
},
|
||||||
Source: extractComponents(bom.Metadata),
|
Source: extractComponents(bom.Metadata),
|
||||||
|
|||||||
@ -141,10 +141,10 @@ func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID {
|
|||||||
return spdx.ElementID(id)
|
return spdx.ElementID(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// packages populates all Package Information from the package Catalog (see https://spdx.github.io/spdx-spec/3-package-information/)
|
// packages populates all Package Information from the package Collection (see https://spdx.github.io/spdx-spec/3-package-information/)
|
||||||
//
|
//
|
||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func toPackages(catalog *pkg.Catalog, sbom sbom.SBOM) (results []*spdx.Package) {
|
func toPackages(catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Package) {
|
||||||
for _, p := range catalog.Sorted() {
|
for _, p := range catalog.Sorted() {
|
||||||
// name should be guaranteed to be unique, but semantically useful and stable
|
// name should be guaranteed to be unique, but semantically useful and stable
|
||||||
id := toSPDXID(p)
|
id := toSPDXID(p)
|
||||||
@ -516,7 +516,7 @@ func toFileTypes(metadata *source.FileMetadata) (ty []string) {
|
|||||||
return ty
|
return ty
|
||||||
}
|
}
|
||||||
|
|
||||||
func toOtherLicenses(catalog *pkg.Catalog) []*spdx.OtherLicense {
|
func toOtherLicenses(catalog *pkg.Collection) []*spdx.OtherLicense {
|
||||||
licenses := map[string]bool{}
|
licenses := map[string]bool{}
|
||||||
for _, p := range catalog.Sorted() {
|
for _, p := range catalog.Sorted() {
|
||||||
for _, license := range parseLicenses(p.Licenses) {
|
for _, license := range parseLicenses(p.Licenses) {
|
||||||
|
|||||||
@ -421,7 +421,7 @@ func Test_H1Digest(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
catalog := pkg.NewCatalog(test.pkg)
|
catalog := pkg.NewCollection(test.pkg)
|
||||||
pkgs := toPackages(catalog, s)
|
pkgs := toPackages(catalog, s)
|
||||||
require.Len(t, pkgs, 1)
|
require.Len(t, pkgs, 1)
|
||||||
for _, p := range pkgs {
|
for _, p := range pkgs {
|
||||||
@ -494,7 +494,7 @@ func Test_OtherLicenses(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
catalog := pkg.NewCatalog(test.pkg)
|
catalog := pkg.NewCollection(test.pkg)
|
||||||
otherLicenses := toOtherLicenses(catalog)
|
otherLicenses := toOtherLicenses(catalog)
|
||||||
require.Len(t, otherLicenses, len(test.expected))
|
require.Len(t, otherLicenses, len(test.expected))
|
||||||
require.Equal(t, test.expected, otherLicenses)
|
require.Equal(t, test.expected, otherLicenses)
|
||||||
|
|||||||
@ -33,7 +33,7 @@ func ToSyftModel(doc *spdx.Document) (*sbom.SBOM, error) {
|
|||||||
s := &sbom.SBOM{
|
s := &sbom.SBOM{
|
||||||
Source: src,
|
Source: src,
|
||||||
Artifacts: sbom.Artifacts{
|
Artifacts: sbom.Artifacts{
|
||||||
PackageCatalog: pkg.NewCatalog(),
|
PackageCatalog: pkg.NewCollection(),
|
||||||
FileMetadata: map[source.Coordinates]source.FileMetadata{},
|
FileMetadata: map[source.Coordinates]source.FileMetadata{},
|
||||||
FileDigests: map[source.Coordinates][]file.Digest{},
|
FileDigests: map[source.Coordinates][]file.Digest{},
|
||||||
LinuxDistribution: findLinuxReleaseByPURL(doc),
|
LinuxDistribution: findLinuxReleaseByPURL(doc),
|
||||||
|
|||||||
@ -28,7 +28,7 @@ func Test_toGithubModel(t *testing.T) {
|
|||||||
VersionID: "18.04",
|
VersionID: "18.04",
|
||||||
IDLike: []string{"debian"},
|
IDLike: []string{"debian"},
|
||||||
},
|
},
|
||||||
PackageCatalog: pkg.NewCatalog(),
|
PackageCatalog: pkg.NewCollection(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, p := range []pkg.Package{
|
for _, p := range []pkg.Package{
|
||||||
|
|||||||
@ -93,7 +93,7 @@ func AssertEncoderAgainstGoldenSnapshot(t *testing.T, format sbom.Format, sbom s
|
|||||||
|
|
||||||
func ImageInput(t testing.TB, testImage string, options ...ImageOption) sbom.SBOM {
|
func ImageInput(t testing.TB, testImage string, options ...ImageOption) sbom.SBOM {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
var cfg imageCfg
|
var cfg imageCfg
|
||||||
var img *image.Image
|
var img *image.Image
|
||||||
for _, opt := range options {
|
for _, opt := range options {
|
||||||
@ -145,7 +145,7 @@ func carriageRedactor(s []byte) []byte {
|
|||||||
return []byte(msg)
|
return []byte(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func populateImageCatalog(catalog *pkg.Catalog, img *image.Image) {
|
func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
|
||||||
_, ref1, _ := img.SquashedTree().File("/somefile-1.txt", filetree.FollowBasenameLinks)
|
_, ref1, _ := img.SquashedTree().File("/somefile-1.txt", filetree.FollowBasenameLinks)
|
||||||
_, ref2, _ := img.SquashedTree().File("/somefile-2.txt", filetree.FollowBasenameLinks)
|
_, ref2, _ := img.SquashedTree().File("/somefile-2.txt", filetree.FollowBasenameLinks)
|
||||||
|
|
||||||
@ -252,8 +252,8 @@ func DirectoryInputWithAuthorField(t testing.TB) sbom.SBOM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDirectoryCatalog() *pkg.Catalog {
|
func newDirectoryCatalog() *pkg.Collection {
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
|
|
||||||
// populate catalog with test data
|
// populate catalog with test data
|
||||||
catalog.Add(pkg.Package{
|
catalog.Add(pkg.Package{
|
||||||
@ -303,8 +303,8 @@ func newDirectoryCatalog() *pkg.Catalog {
|
|||||||
return catalog
|
return catalog
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDirectoryCatalogWithAuthorField() *pkg.Catalog {
|
func newDirectoryCatalogWithAuthorField() *pkg.Collection {
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
|
|
||||||
// populate catalog with test data
|
// populate catalog with test data
|
||||||
catalog.Add(pkg.Package{
|
catalog.Add(pkg.Package{
|
||||||
|
|||||||
@ -49,7 +49,7 @@ func TestSPDXJSONSPDXIDs(t *testing.T) {
|
|||||||
Format(),
|
Format(),
|
||||||
sbom.SBOM{
|
sbom.SBOM{
|
||||||
Artifacts: sbom.Artifacts{
|
Artifacts: sbom.Artifacts{
|
||||||
PackageCatalog: pkg.NewCatalog(pkgs...),
|
PackageCatalog: pkg.NewCollection(pkgs...),
|
||||||
},
|
},
|
||||||
Relationships: nil,
|
Relationships: nil,
|
||||||
Source: source.Metadata{
|
Source: source.Metadata{
|
||||||
|
|||||||
@ -47,7 +47,7 @@ func schemaVersionRedactor(s []byte) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeFullJSONDocument(t *testing.T) {
|
func TestEncodeFullJSONDocument(t *testing.T) {
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
|
|
||||||
p1 := pkg.Package{
|
p1 := pkg.Package{
|
||||||
Name: "package-1",
|
Name: "package-1",
|
||||||
|
|||||||
@ -173,7 +173,7 @@ func toFileType(ty stereoscopeFile.Type) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPackageModels(catalog *pkg.Catalog) []model.Package {
|
func toPackageModels(catalog *pkg.Collection) []model.Package {
|
||||||
artifacts := make([]model.Package, 0)
|
artifacts := make([]model.Package, 0)
|
||||||
if catalog == nil {
|
if catalog == nil {
|
||||||
return artifacts
|
return artifacts
|
||||||
|
|||||||
@ -131,7 +131,7 @@ func toSyftLinuxRelease(d model.LinuxRelease) *linux.Release {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toSyftRelationships(doc *model.Document, catalog *pkg.Catalog, relationships []model.Relationship, idAliases map[string]string) []artifact.Relationship {
|
func toSyftRelationships(doc *model.Document, catalog *pkg.Collection, relationships []model.Relationship, idAliases map[string]string) []artifact.Relationship {
|
||||||
idMap := make(map[string]interface{})
|
idMap := make(map[string]interface{})
|
||||||
|
|
||||||
for _, p := range catalog.Sorted() {
|
for _, p := range catalog.Sorted() {
|
||||||
@ -256,8 +256,8 @@ func toSyftSourceData(s model.Source) *source.Metadata {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toSyftCatalog(pkgs []model.Package, idAliases map[string]string) *pkg.Catalog {
|
func toSyftCatalog(pkgs []model.Package, idAliases map[string]string) *pkg.Collection {
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
for _, p := range pkgs {
|
for _, p := range pkgs {
|
||||||
catalog.Add(toSyftPackage(p, idAliases))
|
catalog.Add(toSyftPackage(p, idAliases))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ import (
|
|||||||
// CatalogPackages takes an inventory of packages from the given image from a particular perspective
|
// CatalogPackages takes an inventory of packages from the given image from a particular perspective
|
||||||
// (e.g. squashed source, all-layers source). Returns the discovered set of packages, the identified Linux
|
// (e.g. squashed source, all-layers source). Returns the discovered set of packages, the identified Linux
|
||||||
// distribution, and the source object used to wrap the data source.
|
// distribution, and the source object used to wrap the data source.
|
||||||
func CatalogPackages(src *source.Source, cfg cataloger.Config) (*pkg.Catalog, []artifact.Relationship, *linux.Release, error) {
|
func CatalogPackages(src *source.Source, cfg cataloger.Config) (*pkg.Collection, []artifact.Relationship, *linux.Release, error) {
|
||||||
resolver, err := src.FileResolver(cfg.Search.Scope)
|
resolver, err := src.FileResolver(cfg.Search.Scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, fmt.Errorf("unable to determine resolver while cataloging packages: %w", err)
|
return nil, nil, nil, fmt.Errorf("unable to determine resolver while cataloging packages: %w", err)
|
||||||
@ -76,7 +76,7 @@ func CatalogPackages(src *source.Source, cfg cataloger.Config) (*pkg.Catalog, []
|
|||||||
return catalog, relationships, release, err
|
return catalog, relationships, release, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSourceRelationshipsFromCatalog(src *source.Source, c *pkg.Catalog) []artifact.Relationship {
|
func newSourceRelationshipsFromCatalog(src *source.Source, c *pkg.Collection) []artifact.Relationship {
|
||||||
relationships := make([]artifact.Relationship, 0) // Should we pre-allocate this by giving catalog a Len() method?
|
relationships := make([]artifact.Relationship, 0) // Should we pre-allocate this by giving catalog a Len() method?
|
||||||
for p := range c.Enumerate() {
|
for p := range c.Enumerate() {
|
||||||
relationships = append(relationships, artifact.Relationship{
|
relationships = append(relationships, artifact.Relationship{
|
||||||
|
|||||||
@ -10,33 +10,8 @@ import (
|
|||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
)
|
)
|
||||||
|
|
||||||
type orderedIDSet struct {
|
// Collection represents a collection of Packages.
|
||||||
slice []artifact.ID
|
type Collection struct {
|
||||||
}
|
|
||||||
|
|
||||||
func (s *orderedIDSet) add(ids ...artifact.ID) {
|
|
||||||
loopNewIDs:
|
|
||||||
for _, newID := range ids {
|
|
||||||
for _, existingID := range s.slice {
|
|
||||||
if existingID == newID {
|
|
||||||
continue loopNewIDs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s.slice = append(s.slice, newID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *orderedIDSet) delete(id artifact.ID) {
|
|
||||||
for i, existingID := range s.slice {
|
|
||||||
if existingID == id {
|
|
||||||
s.slice = append(s.slice[:i], s.slice[i+1:]...)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Catalog represents a collection of Packages.
|
|
||||||
type Catalog struct {
|
|
||||||
byID map[artifact.ID]Package
|
byID map[artifact.ID]Package
|
||||||
idsByName map[string]orderedIDSet
|
idsByName map[string]orderedIDSet
|
||||||
idsByType map[Type]orderedIDSet
|
idsByType map[Type]orderedIDSet
|
||||||
@ -44,9 +19,9 @@ type Catalog struct {
|
|||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCatalog returns a new empty Catalog
|
// NewCollection returns a new empty Collection
|
||||||
func NewCatalog(pkgs ...Package) *Catalog {
|
func NewCollection(pkgs ...Package) *Collection {
|
||||||
catalog := Catalog{
|
catalog := Collection{
|
||||||
byID: make(map[artifact.ID]Package),
|
byID: make(map[artifact.ID]Package),
|
||||||
idsByName: make(map[string]orderedIDSet),
|
idsByName: make(map[string]orderedIDSet),
|
||||||
idsByType: make(map[Type]orderedIDSet),
|
idsByType: make(map[Type]orderedIDSet),
|
||||||
@ -61,12 +36,12 @@ func NewCatalog(pkgs ...Package) *Catalog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PackageCount returns the total number of packages that have been added.
|
// PackageCount returns the total number of packages that have been added.
|
||||||
func (c *Catalog) PackageCount() int {
|
func (c *Collection) PackageCount() int {
|
||||||
return len(c.byID)
|
return len(c.byID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Package returns the package with the given ID.
|
// Package returns the package with the given ID.
|
||||||
func (c *Catalog) Package(id artifact.ID) *Package {
|
func (c *Collection) Package(id artifact.ID) *Package {
|
||||||
v, exists := c.byID[id]
|
v, exists := c.byID[id]
|
||||||
if !exists {
|
if !exists {
|
||||||
return nil
|
return nil
|
||||||
@ -81,17 +56,17 @@ func (c *Catalog) Package(id artifact.ID) *Package {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PackagesByPath returns all packages that were discovered from the given path.
|
// PackagesByPath returns all packages that were discovered from the given path.
|
||||||
func (c *Catalog) PackagesByPath(path string) []Package {
|
func (c *Collection) PackagesByPath(path string) []Package {
|
||||||
return c.Packages(c.idsByPath[path].slice)
|
return c.Packages(c.idsByPath[path].slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PackagesByName returns all packages that were discovered with a matching name.
|
// PackagesByName returns all packages that were discovered with a matching name.
|
||||||
func (c *Catalog) PackagesByName(name string) []Package {
|
func (c *Collection) PackagesByName(name string) []Package {
|
||||||
return c.Packages(c.idsByName[name].slice)
|
return c.Packages(c.idsByName[name].slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Packages returns all packages for the given ID.
|
// Packages returns all packages for the given ID.
|
||||||
func (c *Catalog) Packages(ids []artifact.ID) (result []Package) {
|
func (c *Collection) Packages(ids []artifact.ID) (result []Package) {
|
||||||
for _, i := range ids {
|
for _, i := range ids {
|
||||||
p, exists := c.byID[i]
|
p, exists := c.byID[i]
|
||||||
if exists {
|
if exists {
|
||||||
@ -102,7 +77,7 @@ func (c *Catalog) Packages(ids []artifact.ID) (result []Package) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add n packages to the catalog.
|
// Add n packages to the catalog.
|
||||||
func (c *Catalog) Add(pkgs ...Package) {
|
func (c *Collection) Add(pkgs ...Package) {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
@ -129,26 +104,26 @@ func (c *Catalog) Add(pkgs ...Package) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) addToIndex(p Package) {
|
func (c *Collection) addToIndex(p Package) {
|
||||||
c.byID[p.id] = p
|
c.byID[p.id] = p
|
||||||
c.addNameToIndex(p)
|
c.addNameToIndex(p)
|
||||||
c.addTypeToIndex(p)
|
c.addTypeToIndex(p)
|
||||||
c.addPathsToIndex(p)
|
c.addPathsToIndex(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) addNameToIndex(p Package) {
|
func (c *Collection) addNameToIndex(p Package) {
|
||||||
nameIndex := c.idsByName[p.Name]
|
nameIndex := c.idsByName[p.Name]
|
||||||
nameIndex.add(p.id)
|
nameIndex.add(p.id)
|
||||||
c.idsByName[p.Name] = nameIndex
|
c.idsByName[p.Name] = nameIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) addTypeToIndex(p Package) {
|
func (c *Collection) addTypeToIndex(p Package) {
|
||||||
typeIndex := c.idsByType[p.Type]
|
typeIndex := c.idsByType[p.Type]
|
||||||
typeIndex.add(p.id)
|
typeIndex.add(p.id)
|
||||||
c.idsByType[p.Type] = typeIndex
|
c.idsByType[p.Type] = typeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) addPathsToIndex(p Package) {
|
func (c *Collection) addPathsToIndex(p Package) {
|
||||||
observedPaths := internal.NewStringSet()
|
observedPaths := internal.NewStringSet()
|
||||||
for _, l := range p.Locations.ToSlice() {
|
for _, l := range p.Locations.ToSlice() {
|
||||||
if l.RealPath != "" && !observedPaths.Contains(l.RealPath) {
|
if l.RealPath != "" && !observedPaths.Contains(l.RealPath) {
|
||||||
@ -162,13 +137,13 @@ func (c *Catalog) addPathsToIndex(p Package) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) addPathToIndex(id artifact.ID, path string) {
|
func (c *Collection) addPathToIndex(id artifact.ID, path string) {
|
||||||
pathIndex := c.idsByPath[path]
|
pathIndex := c.idsByPath[path]
|
||||||
pathIndex.add(id)
|
pathIndex.add(id)
|
||||||
c.idsByPath[path] = pathIndex
|
c.idsByPath[path] = pathIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) Delete(ids ...artifact.ID) {
|
func (c *Collection) Delete(ids ...artifact.ID) {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
@ -185,19 +160,19 @@ func (c *Catalog) Delete(ids ...artifact.ID) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) deleteNameFromIndex(p Package) {
|
func (c *Collection) deleteNameFromIndex(p Package) {
|
||||||
nameIndex := c.idsByName[p.Name]
|
nameIndex := c.idsByName[p.Name]
|
||||||
nameIndex.delete(p.id)
|
nameIndex.delete(p.id)
|
||||||
c.idsByName[p.Name] = nameIndex
|
c.idsByName[p.Name] = nameIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) deleteTypeFromIndex(p Package) {
|
func (c *Collection) deleteTypeFromIndex(p Package) {
|
||||||
typeIndex := c.idsByType[p.Type]
|
typeIndex := c.idsByType[p.Type]
|
||||||
typeIndex.delete(p.id)
|
typeIndex.delete(p.id)
|
||||||
c.idsByType[p.Type] = typeIndex
|
c.idsByType[p.Type] = typeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) deletePathsFromIndex(p Package) {
|
func (c *Collection) deletePathsFromIndex(p Package) {
|
||||||
observedPaths := internal.NewStringSet()
|
observedPaths := internal.NewStringSet()
|
||||||
for _, l := range p.Locations.ToSlice() {
|
for _, l := range p.Locations.ToSlice() {
|
||||||
if l.RealPath != "" && !observedPaths.Contains(l.RealPath) {
|
if l.RealPath != "" && !observedPaths.Contains(l.RealPath) {
|
||||||
@ -211,7 +186,7 @@ func (c *Catalog) deletePathsFromIndex(p Package) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Catalog) deletePathFromIndex(id artifact.ID, path string) {
|
func (c *Collection) deletePathFromIndex(id artifact.ID, path string) {
|
||||||
pathIndex := c.idsByPath[path]
|
pathIndex := c.idsByPath[path]
|
||||||
pathIndex.delete(id)
|
pathIndex.delete(id)
|
||||||
if len(pathIndex.slice) == 0 {
|
if len(pathIndex.slice) == 0 {
|
||||||
@ -222,7 +197,7 @@ func (c *Catalog) deletePathFromIndex(id artifact.ID, path string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enumerate all packages for the given type(s), enumerating all packages if no type is specified.
|
// Enumerate all packages for the given type(s), enumerating all packages if no type is specified.
|
||||||
func (c *Catalog) Enumerate(types ...Type) <-chan Package {
|
func (c *Collection) Enumerate(types ...Type) <-chan Package {
|
||||||
channel := make(chan Package)
|
channel := make(chan Package)
|
||||||
go func() {
|
go func() {
|
||||||
defer close(channel)
|
defer close(channel)
|
||||||
@ -257,7 +232,7 @@ func (c *Catalog) Enumerate(types ...Type) <-chan Package {
|
|||||||
|
|
||||||
// Sorted enumerates all packages for the given types sorted by package name. Enumerates all packages if no type
|
// Sorted enumerates all packages for the given types sorted by package name. Enumerates all packages if no type
|
||||||
// is specified.
|
// is specified.
|
||||||
func (c *Catalog) Sorted(types ...Type) (pkgs []Package) {
|
func (c *Collection) Sorted(types ...Type) (pkgs []Package) {
|
||||||
for p := range c.Enumerate(types...) {
|
for p := range c.Enumerate(types...) {
|
||||||
pkgs = append(pkgs, p)
|
pkgs = append(pkgs, p)
|
||||||
}
|
}
|
||||||
@ -266,3 +241,28 @@ func (c *Catalog) Sorted(types ...Type) (pkgs []Package) {
|
|||||||
|
|
||||||
return pkgs
|
return pkgs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type orderedIDSet struct {
|
||||||
|
slice []artifact.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *orderedIDSet) add(ids ...artifact.ID) {
|
||||||
|
loopNewIDs:
|
||||||
|
for _, newID := range ids {
|
||||||
|
for _, existingID := range s.slice {
|
||||||
|
if existingID == newID {
|
||||||
|
continue loopNewIDs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.slice = append(s.slice, newID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *orderedIDSet) delete(id artifact.ID) {
|
||||||
|
for i, existingID := range s.slice {
|
||||||
|
if existingID == id {
|
||||||
|
s.slice = append(s.slice[:i], s.slice[i+1:]...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -145,7 +145,7 @@ func TestCatalogDeleteRemovesPackages(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
c := NewCatalog()
|
c := NewCollection()
|
||||||
for _, p := range test.pkgs {
|
for _, p := range test.pkgs {
|
||||||
c.Add(p)
|
c.Add(p)
|
||||||
}
|
}
|
||||||
@ -212,13 +212,13 @@ func TestCatalogAddPopulatesIndex(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
c := NewCatalog(pkgs...)
|
c := NewCollection(pkgs...)
|
||||||
assertIndexes(t, c, test.expectedIndexes)
|
assertIndexes(t, c, test.expectedIndexes)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertIndexes(t *testing.T, c *Catalog, expectedIndexes expectedIndexes) {
|
func assertIndexes(t *testing.T, c *Collection, expectedIndexes expectedIndexes) {
|
||||||
// assert path index
|
// assert path index
|
||||||
assert.Len(t, c.idsByPath, len(expectedIndexes.byPath), "unexpected path index length")
|
assert.Len(t, c.idsByPath, len(expectedIndexes.byPath), "unexpected path index length")
|
||||||
for path, expectedIds := range expectedIndexes.byPath {
|
for path, expectedIds := range expectedIndexes.byPath {
|
||||||
@ -306,7 +306,7 @@ func TestCatalog_PathIndexDeduplicatesRealVsVirtualPaths(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
for _, path := range test.paths {
|
for _, path := range test.paths {
|
||||||
actualPackages := NewCatalog(test.pkgs...).PackagesByPath(path)
|
actualPackages := NewCollection(test.pkgs...).PackagesByPath(path)
|
||||||
require.Len(t, actualPackages, 1)
|
require.Len(t, actualPackages, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -373,7 +373,7 @@ func TestCatalog_MergeRecords(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
actual := NewCatalog(tt.pkgs...).PackagesByPath("/b/path")
|
actual := NewCollection(tt.pkgs...).PackagesByPath("/b/path")
|
||||||
require.Len(t, actual, 1)
|
require.Len(t, actual, 1)
|
||||||
assert.Equal(t, tt.expectedLocations, actual[0].Locations.ToSlice())
|
assert.Equal(t, tt.expectedLocations, actual[0].Locations.ToSlice())
|
||||||
require.Len(t, actual[0].CPEs, tt.expectedCPECount)
|
require.Len(t, actual[0].CPEs, tt.expectedCPECount)
|
||||||
@ -382,7 +382,7 @@ func TestCatalog_MergeRecords(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestCatalog_EnumerateNilCatalog(t *testing.T) {
|
func TestCatalog_EnumerateNilCatalog(t *testing.T) {
|
||||||
var c *Catalog
|
var c *Collection
|
||||||
assert.Empty(t, c.Enumerate())
|
assert.Empty(t, c.Enumerate())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -105,8 +105,8 @@ func runCataloger(cataloger pkg.Cataloger, resolver source.FileResolver) (catalo
|
|||||||
// request.
|
// request.
|
||||||
//
|
//
|
||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func Catalog(resolver source.FileResolver, _ *linux.Release, parallelism int, catalogers ...pkg.Cataloger) (*pkg.Catalog, []artifact.Relationship, error) {
|
func Catalog(resolver source.FileResolver, _ *linux.Release, parallelism int, catalogers ...pkg.Cataloger) (*pkg.Collection, []artifact.Relationship, error) {
|
||||||
catalog := pkg.NewCatalog()
|
catalog := pkg.NewCollection()
|
||||||
var allRelationships []artifact.Relationship
|
var allRelationships []artifact.Relationship
|
||||||
|
|
||||||
filesProcessed, packagesDiscovered := newMonitor()
|
filesProcessed, packagesDiscovered := newMonitor()
|
||||||
|
|||||||
9
syft/pkg/deprecated.go
Normal file
9
syft/pkg/deprecated.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package pkg
|
||||||
|
|
||||||
|
// Deprecated: use Collection instead
|
||||||
|
type Catalog = Collection
|
||||||
|
|
||||||
|
// Deprecated: use NewCollection() instead
|
||||||
|
func NewCatalog(pkgs ...Package) *Catalog {
|
||||||
|
return NewCollection(pkgs...)
|
||||||
|
}
|
||||||
@ -2,7 +2,7 @@ package pkg
|
|||||||
|
|
||||||
import "github.com/anchore/syft/syft/artifact"
|
import "github.com/anchore/syft/syft/artifact"
|
||||||
|
|
||||||
func NewRelationships(catalog *Catalog) []artifact.Relationship {
|
func NewRelationships(catalog *Collection) []artifact.Relationship {
|
||||||
rels := RelationshipsByFileOwnership(catalog)
|
rels := RelationshipsByFileOwnership(catalog)
|
||||||
rels = append(rels, RelationshipsEvidentBy(catalog)...)
|
rels = append(rels, RelationshipsEvidentBy(catalog)...)
|
||||||
return rels
|
return rels
|
||||||
|
|||||||
@ -31,7 +31,7 @@ type ownershipByFilesMetadata struct {
|
|||||||
|
|
||||||
// RelationshipsByFileOwnership creates a package-to-package relationship based on discovering which packages have
|
// RelationshipsByFileOwnership creates a package-to-package relationship based on discovering which packages have
|
||||||
// evidence locations that overlap with ownership claim from another package's package manager metadata.
|
// evidence locations that overlap with ownership claim from another package's package manager metadata.
|
||||||
func RelationshipsByFileOwnership(catalog *Catalog) []artifact.Relationship {
|
func RelationshipsByFileOwnership(catalog *Collection) []artifact.Relationship {
|
||||||
var relationships = findOwnershipByFilesRelationships(catalog)
|
var relationships = findOwnershipByFilesRelationships(catalog)
|
||||||
|
|
||||||
var edges []artifact.Relationship
|
var edges []artifact.Relationship
|
||||||
@ -55,7 +55,7 @@ func RelationshipsByFileOwnership(catalog *Catalog) []artifact.Relationship {
|
|||||||
|
|
||||||
// findOwnershipByFilesRelationships find overlaps in file ownership with a file that defines another package. Specifically, a .Location.Path of
|
// findOwnershipByFilesRelationships find overlaps in file ownership with a file that defines another package. Specifically, a .Location.Path of
|
||||||
// a package is found to be owned by another (from the owner's .Metadata.Files[]).
|
// a package is found to be owned by another (from the owner's .Metadata.Files[]).
|
||||||
func findOwnershipByFilesRelationships(catalog *Catalog) map[artifact.ID]map[artifact.ID]*strset.Set {
|
func findOwnershipByFilesRelationships(catalog *Collection) map[artifact.ID]map[artifact.ID]*strset.Set {
|
||||||
var relationships = make(map[artifact.ID]map[artifact.ID]*strset.Set)
|
var relationships = make(map[artifact.ID]map[artifact.ID]*strset.Set)
|
||||||
|
|
||||||
if catalog == nil {
|
if catalog == nil {
|
||||||
|
|||||||
@ -139,7 +139,7 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
pkgs, expectedRelations := test.setup(t)
|
pkgs, expectedRelations := test.setup(t)
|
||||||
c := NewCatalog(pkgs...)
|
c := NewCollection(pkgs...)
|
||||||
relationships := RelationshipsByFileOwnership(c)
|
relationships := RelationshipsByFileOwnership(c)
|
||||||
|
|
||||||
assert.Len(t, relationships, len(expectedRelations))
|
assert.Len(t, relationships, len(expectedRelations))
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RelationshipsEvidentBy(catalog *Catalog) []artifact.Relationship {
|
func RelationshipsEvidentBy(catalog *Collection) []artifact.Relationship {
|
||||||
var edges []artifact.Relationship
|
var edges []artifact.Relationship
|
||||||
for _, p := range catalog.Sorted() {
|
for _, p := range catalog.Sorted() {
|
||||||
for _, l := range p.Locations.ToSlice() {
|
for _, l := range p.Locations.ToSlice() {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func TestRelationshipsEvidentBy(t *testing.T) {
|
func TestRelationshipsEvidentBy(t *testing.T) {
|
||||||
|
|
||||||
c := NewCatalog()
|
c := NewCollection()
|
||||||
|
|
||||||
coordA := source.Coordinates{
|
coordA := source.Coordinates{
|
||||||
RealPath: "/somewhere/real",
|
RealPath: "/somewhere/real",
|
||||||
@ -53,7 +53,7 @@ func TestRelationshipsEvidentBy(t *testing.T) {
|
|||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
catalog *Catalog
|
catalog *Collection
|
||||||
want []artifact.Relationship
|
want []artifact.Relationship
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
|||||||
@ -20,7 +20,7 @@ type SBOM struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Artifacts struct {
|
type Artifacts struct {
|
||||||
PackageCatalog *pkg.Catalog
|
PackageCatalog *pkg.Collection
|
||||||
FileMetadata map[source.Coordinates]source.FileMetadata
|
FileMetadata map[source.Coordinates]source.FileMetadata
|
||||||
FileDigests map[source.Coordinates][]file.Digest
|
FileDigests map[source.Coordinates][]file.Digest
|
||||||
FileContents map[source.Coordinates]string
|
FileContents map[source.Coordinates]string
|
||||||
|
|||||||
@ -22,7 +22,7 @@ func BenchmarkImagePackageCatalogers(b *testing.B) {
|
|||||||
imagetest.GetFixtureImage(b, "docker-archive", fixtureImageName)
|
imagetest.GetFixtureImage(b, "docker-archive", fixtureImageName)
|
||||||
tarPath := imagetest.GetFixtureImageTarPath(b, fixtureImageName)
|
tarPath := imagetest.GetFixtureImageTarPath(b, fixtureImageName)
|
||||||
|
|
||||||
var pc *pkg.Catalog
|
var pc *pkg.Collection
|
||||||
for _, c := range cataloger.ImageCatalogers(cataloger.DefaultConfig()) {
|
for _, c := range cataloger.ImageCatalogers(cataloger.DefaultConfig()) {
|
||||||
// in case of future alteration where state is persisted, assume no dependency is safe to reuse
|
// in case of future alteration where state is persisted, assume no dependency is safe to reuse
|
||||||
userInput := "docker-archive:" + tarPath
|
userInput := "docker-archive:" + tarPath
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user