From 7bdd6e3ab05edc8ee55ccf75e611abffa5e38a2d Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Wed, 17 Nov 2021 13:39:51 -0500 Subject: [PATCH] add coordinate set Signed-off-by: Alex Goodman --- syft/source/coordinates.go | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/syft/source/coordinates.go b/syft/source/coordinates.go index a2e2d6200..049f418b7 100644 --- a/syft/source/coordinates.go +++ b/syft/source/coordinates.go @@ -2,6 +2,7 @@ package source import ( "fmt" + "sort" "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/artifact" @@ -13,6 +14,18 @@ type Coordinates struct { FileSystemID string `json:"layerID,omitempty"` // An ID representing the filesystem. For container images, this is a layer digest. For directories or a root filesystem, this is blank. } +// CoordinateSet represents a set of string types. +type CoordinateSet map[Coordinates]struct{} + +// NewCoordinateSet creates a CoordinateSet populated with values from the given slice. +func NewCoordinateSet(start ...Coordinates) CoordinateSet { + ret := make(CoordinateSet) + for _, s := range start { + ret.Add(s) + } + return ret +} + func (c Coordinates) ID() artifact.ID { f, err := artifact.IDFromHash(c) if err != nil { @@ -32,3 +45,37 @@ func (c Coordinates) String() string { } return fmt.Sprintf("Location<%s>", str) } + +// Add a string to the set. +func (s CoordinateSet) Add(i Coordinates) { + s[i] = struct{}{} +} + +// Remove a string from the set. +func (s CoordinateSet) Remove(i Coordinates) { + delete(s, i) +} + +// Contains indicates if the given string is contained within the set. +func (s CoordinateSet) Contains(i Coordinates) bool { + _, ok := s[i] + return ok +} + +// ToSlice returns a sorted slice of Locations that are contained within the set. +func (s CoordinateSet) ToSlice() []Coordinates { + ret := make([]Coordinates, len(s)) + idx := 0 + for v := range s { + ret[idx] = v + idx++ + } + + sort.SliceStable(ret, func(i, j int) bool { + if ret[i].RealPath == ret[j].RealPath { + return ret[i].FileSystemID < ret[j].FileSystemID + } + return ret[i].RealPath < ret[j].RealPath + }) + return ret +}