Use cataloger Sorted() output instead of Enumerate() for stable result sorting in presenters. Fixes #331

Also adds artifact location to sort key for Sorted() to ensure
consistent sorts when artifacts of same name, version, and type are
found in different locations in the image. Location should be sufficient
since we assume only one package of a given name and version can exist
in one location, even if that location is an package-db like rpmdb.

Signed-off-by: Zach Hill <zach@anchore.com>
This commit is contained in:
Zach Hill 2021-04-01 01:05:00 -07:00
parent 485caa1ea3
commit c332ba0867
3 changed files with 5 additions and 2 deletions

View file

@ -34,7 +34,7 @@ func NewCycloneDxDocument(catalog *pkg.Catalog, srcMetadata source.Metadata) Cyc
}
// attach components
for p := range catalog.Enumerate() {
for _, p := range catalog.Sorted() {
component := CycloneDxComponent{
Type: "library", // TODO: this is not accurate
Name: p.Name,

View file

@ -25,7 +25,7 @@ func (pres *TablePresenter) Present(output io.Writer) error {
rows := make([][]string, 0)
columns := []string{"Name", "Version", "Type"}
for p := range pres.catalog.Enumerate() {
for _, p := range pres.catalog.Sorted() {
row := []string{
p.Name,
p.Version,

View file

@ -164,6 +164,9 @@ func (c *Catalog) Sorted(types ...Type) []*Package {
sort.SliceStable(pkgs, func(i, j int) bool {
if pkgs[i].Name == pkgs[j].Name {
if pkgs[i].Version == pkgs[j].Version {
if pkgs[i].Type == pkgs[j].Type {
return pkgs[i].Locations[0].String() < pkgs[j].Locations[0].String()
}
return pkgs[i].Type < pkgs[j].Type
}
return pkgs[i].Version < pkgs[j].Version