mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
migrate pkg.ID and pkg.Relationship to artifact package
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
9bbc9ff633
commit
a906b9a03a
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package pkg
|
||||
package artifact
|
||||
|
||||
// ID represents a unique value for each package added to a package catalog.
|
||||
type ID string
|
||||
15
syft/artifact/relationship.go
Normal file
15
syft/artifact/relationship.go
Normal 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{}
|
||||
}
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}{
|
||||
{
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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",
|
||||
},
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
8
syft/pkg/relationships.go
Normal file
8
syft/pkg/relationships.go
Normal 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)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user