migrate pkg.ID and pkg.Relationship to artifact package

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2021-11-08 15:53:28 -05:00
parent 9bbc9ff633
commit a906b9a03a
No known key found for this signature in database
GPG Key ID: 5CB45AE22BAB7EA7
11 changed files with 75 additions and 60 deletions

View File

@ -3,6 +3,8 @@ package syftjson
import (
"fmt"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/sbom"
"github.com/anchore/syft/internal"
@ -87,14 +89,14 @@ func toPackageModel(p *pkg.Package) model.Package {
}
}
func toRelationshipModel(relationships []pkg.Relationship) []model.Relationship {
func toRelationshipModel(relationships []artifact.Relationship) []model.Relationship {
result := make([]model.Relationship, len(relationships))
for i, r := range relationships {
result[i] = model.Relationship{
Parent: string(r.Parent),
Child: string(r.Child),
Parent: string(r.From),
Child: string(r.To),
Type: string(r.Type),
Metadata: r.Metadata,
Metadata: r.Data,
}
}
return result

View File

@ -3,6 +3,7 @@ package syftjson
import (
"github.com/anchore/syft/internal/formats/syftjson/model"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/sbom"
@ -61,7 +62,7 @@ func toSyftPackage(p model.Package) pkg.Package {
}
return pkg.Package{
ID: pkg.ID(p.ID),
ID: artifact.ID(p.ID),
Name: p.Name,
Version: p.Version,
FoundBy: p.FoundBy,

View File

@ -1,4 +1,4 @@
package pkg
package artifact
// ID represents a unique value for each package added to a package catalog.
type ID string

View File

@ -0,0 +1,15 @@
package artifact
const (
// OwnershipByFileOverlapRelationship indicates that the parent package owns the child package made evident by the set of provided files
OwnershipByFileOverlapRelationship RelationshipType = "ownership-by-file-overlap"
)
type RelationshipType string
type Relationship struct {
From ID
To ID
Type RelationshipType
Data interface{}
}

View File

@ -4,6 +4,8 @@ import (
"sort"
"sync"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
@ -11,18 +13,18 @@ import (
// Catalog represents a collection of Packages.
type Catalog struct {
byID map[ID]*Package
idsByType map[Type][]ID
idsByPath map[string][]ID // note: this is real path or virtual path
byID map[artifact.ID]*Package
idsByType map[Type][]artifact.ID
idsByPath map[string][]artifact.ID // note: this is real path or virtual path
lock sync.RWMutex
}
// NewCatalog returns a new empty Catalog
func NewCatalog(pkgs ...Package) *Catalog {
catalog := Catalog{
byID: make(map[ID]*Package),
idsByType: make(map[Type][]ID),
idsByPath: make(map[string][]ID),
byID: make(map[artifact.ID]*Package),
idsByType: make(map[Type][]artifact.ID),
idsByPath: make(map[string][]artifact.ID),
}
for _, p := range pkgs {
@ -38,7 +40,7 @@ func (c *Catalog) PackageCount() int {
}
// Package returns the package with the given ID.
func (c *Catalog) Package(id ID) *Package {
func (c *Catalog) Package(id artifact.ID) *Package {
v, exists := c.byID[id]
if !exists {
return nil
@ -52,7 +54,7 @@ func (c *Catalog) PackagesByPath(path string) []*Package {
}
// Packages returns all packages for the given ID.
func (c *Catalog) Packages(ids []ID) (result []*Package) {
func (c *Catalog) Packages(ids []artifact.ID) (result []*Package) {
for _, i := range ids {
p, exists := c.byID[i]
if exists {
@ -74,7 +76,7 @@ func (c *Catalog) Add(p Package) {
return
}
p.ID = ID(fingerprint)
p.ID = artifact.ID(fingerprint)
}
// store by package ID
@ -97,7 +99,7 @@ func (c *Catalog) Add(p Package) {
}
}
func (c *Catalog) Remove(id ID) {
func (c *Catalog) Remove(id artifact.ID) {
c.lock.Lock()
defer c.lock.Unlock()
@ -177,7 +179,7 @@ func (c *Catalog) Sorted(types ...Type) []*Package {
return pkgs
}
func removeID(id ID, target []ID) (result []ID) {
func removeID(id artifact.ID, target []artifact.ID) (result []artifact.ID) {
for _, value := range target {
if value != id {
result = append(result, value)

View File

@ -3,6 +3,8 @@ package pkg
import (
"testing"
"github.com/anchore/syft/syft/artifact"
"github.com/scylladb/go-set/strset"
"github.com/anchore/syft/syft/source"
@ -84,7 +86,7 @@ func TestCatalogRemove(t *testing.T) {
tests := []struct {
name string
pkgs []Package
removeId ID
removeId artifact.ID
expectedIndexes expectedIndexes
}{
{

View File

@ -2,6 +2,7 @@ package pkg
import (
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/bmatcuk/doublestar/v2"
"github.com/scylladb/go-set/strset"
)
@ -20,17 +21,17 @@ type ownershipByFilesMetadata struct {
Files []string `json:"files"`
}
func ownershipByFilesRelationships(catalog *Catalog) []Relationship {
func ownershipByFilesRelationships(catalog *Catalog) []artifact.Relationship {
var relationships = findOwnershipByFilesRelationships(catalog)
var edges []Relationship
var edges []artifact.Relationship
for parent, children := range relationships {
for child, files := range children {
edges = append(edges, Relationship{
Parent: parent,
Child: child,
Type: OwnershipByFileOverlapRelationship,
Metadata: ownershipByFilesMetadata{
edges = append(edges, artifact.Relationship{
From: parent,
To: child,
Type: artifact.OwnershipByFileOverlapRelationship,
Data: ownershipByFilesMetadata{
Files: files.List(),
},
})
@ -42,8 +43,8 @@ func ownershipByFilesRelationships(catalog *Catalog) []Relationship {
// 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[]).
func findOwnershipByFilesRelationships(catalog *Catalog) map[ID]map[ID]*strset.Set {
var relationships = make(map[ID]map[ID]*strset.Set)
func findOwnershipByFilesRelationships(catalog *Catalog) map[artifact.ID]map[artifact.ID]*strset.Set {
var relationships = make(map[artifact.ID]map[artifact.ID]*strset.Set)
if catalog == nil {
return relationships
@ -72,7 +73,7 @@ func findOwnershipByFilesRelationships(catalog *Catalog) map[ID]map[ID]*strset.S
continue
}
if _, exists := relationships[candidateOwnerPkg.ID]; !exists {
relationships[candidateOwnerPkg.ID] = make(map[ID]*strset.Set)
relationships[candidateOwnerPkg.ID] = make(map[artifact.ID]*strset.Set)
}
if _, exists := relationships[candidateOwnerPkg.ID][subPackage.ID]; !exists {

View File

@ -3,6 +3,8 @@ package pkg
import (
"testing"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/source"
"github.com/go-test/deep"
)
@ -11,7 +13,7 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
tests := []struct {
name string
pkgs []Package
expectedRelations []Relationship
expectedRelations []artifact.Relationship
}{
{
name: "owns-by-real-path",
@ -53,12 +55,12 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
Type: NpmPkg,
},
},
expectedRelations: []Relationship{
expectedRelations: []artifact.Relationship{
{
Parent: "parent",
Child: "child",
Type: OwnershipByFileOverlapRelationship,
Metadata: ownershipByFilesMetadata{
From: "parent",
To: "child",
Type: artifact.OwnershipByFileOverlapRelationship,
Data: ownershipByFilesMetadata{
Files: []string{
"/d/path",
},
@ -106,12 +108,12 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
Type: NpmPkg,
},
},
expectedRelations: []Relationship{
expectedRelations: []artifact.Relationship{
{
Parent: "parent",
Child: "child",
Type: OwnershipByFileOverlapRelationship,
Metadata: ownershipByFilesMetadata{
From: "parent",
To: "child",
Type: artifact.OwnershipByFileOverlapRelationship,
Data: ownershipByFilesMetadata{
Files: []string{
"/another/path",
},

View File

@ -6,6 +6,8 @@ package pkg
import (
"fmt"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/source"
"github.com/mitchellh/hashstructure"
)
@ -13,7 +15,7 @@ import (
// Package represents an application or library that has been bundled into a distributable format.
// TODO: if we ignore FoundBy for ID generation should we merge the field to show it was found in two places?
type Package struct {
ID ID `hash:"ignore"` // uniquely identifies a package, set by the cataloger
ID artifact.ID `hash:"ignore"` // uniquely identifies a package, set by the cataloger
Name string // the package name
Version string // the version of the package
FoundBy string // the specific cataloger that discovered this package

View File

@ -1,20 +0,0 @@
package pkg
const (
// OwnershipByFileOverlapRelationship indicates that the parent package owns the child package made evident by the set of provided files
OwnershipByFileOverlapRelationship RelationshipType = "ownership-by-file-overlap"
)
type RelationshipType string
type Relationship struct {
Parent ID
Child ID
Type RelationshipType
Metadata interface{}
}
// TODO: as more relationships are added, this function signature will probably accommodate selection
func NewRelationships(catalog *Catalog) []Relationship {
return ownershipByFilesRelationships(catalog)
}

View File

@ -0,0 +1,8 @@
package pkg
import "github.com/anchore/syft/syft/artifact"
// TODO: as more relationships are added, this function signature will probably accommodate selection
func NewRelationships(catalog *Catalog) []artifact.Relationship {
return ownershipByFilesRelationships(catalog)
}