From c332ba0867af9b0e8fb2f9e06fdcf6357ceb11ad Mon Sep 17 00:00:00 2001 From: Zach Hill Date: Thu, 1 Apr 2021 01:05:00 -0700 Subject: [PATCH] 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 --- internal/presenter/packages/cyclonedx_document.go | 2 +- internal/presenter/packages/table_presenter.go | 2 +- syft/pkg/catalog.go | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/internal/presenter/packages/cyclonedx_document.go b/internal/presenter/packages/cyclonedx_document.go index 9278dc6d1..b11bb8006 100644 --- a/internal/presenter/packages/cyclonedx_document.go +++ b/internal/presenter/packages/cyclonedx_document.go @@ -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, diff --git a/internal/presenter/packages/table_presenter.go b/internal/presenter/packages/table_presenter.go index aefaa7286..87256da77 100644 --- a/internal/presenter/packages/table_presenter.go +++ b/internal/presenter/packages/table_presenter.go @@ -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, diff --git a/syft/pkg/catalog.go b/syft/pkg/catalog.go index c6cf47c77..7f1802e24 100644 --- a/syft/pkg/catalog.go +++ b/syft/pkg/catalog.go @@ -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