From b13ffdd30466827a9444f272ae28dab7968f4f40 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 16 Apr 2025 10:41:48 -0400 Subject: [PATCH] fix: comma separated selectors in cataloger list command (#3804) Signed-off-by: Keith Zantow --- cmd/syft/internal/commands/cataloger_list.go | 9 ++-- .../internal/commands/cataloger_list_test.go | 43 +++++++++++++++++-- cmd/syft/internal/options/catalog.go | 12 +++--- cmd/syft/internal/options/catalog_test.go | 2 +- 4 files changed, 53 insertions(+), 13 deletions(-) diff --git a/cmd/syft/internal/commands/cataloger_list.go b/cmd/syft/internal/commands/cataloger_list.go index 65c0c73a9..1dcb4b121 100644 --- a/cmd/syft/internal/commands/cataloger_list.go +++ b/cmd/syft/internal/commands/cataloger_list.go @@ -13,6 +13,7 @@ import ( "github.com/spf13/cobra" "github.com/anchore/clio" + "github.com/anchore/syft/cmd/syft/internal/options" "github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/task" "github.com/anchore/syft/syft/cataloging" @@ -86,11 +87,13 @@ func runCatalogerList(opts *catalogerListOptions) error { } func catalogerListReport(opts *catalogerListOptions, allTaskGroups [][]task.Task) (string, error) { + defaultCatalogers := options.Flatten(opts.DefaultCatalogers) + selectCatalogers := options.Flatten(opts.SelectCatalogers) selectedTaskGroups, selectionEvidence, err := task.SelectInGroups( allTaskGroups, cataloging.NewSelectionRequest(). - WithDefaults(opts.DefaultCatalogers...). - WithExpression(opts.SelectCatalogers...), + WithDefaults(defaultCatalogers...). + WithExpression(selectCatalogers...), ) if err != nil { return "", fmt.Errorf("unable to select catalogers: %w", err) @@ -99,7 +102,7 @@ func catalogerListReport(opts *catalogerListOptions, allTaskGroups [][]task.Task switch opts.Output { case "json": - report, err = renderCatalogerListJSON(flattenTaskGroups(selectedTaskGroups), selectionEvidence, opts.DefaultCatalogers, opts.SelectCatalogers) + report, err = renderCatalogerListJSON(flattenTaskGroups(selectedTaskGroups), selectionEvidence, defaultCatalogers, selectCatalogers) case "table", "": if opts.ShowHidden { report = renderCatalogerListTables(allTaskGroups, selectionEvidence) diff --git a/cmd/syft/internal/commands/cataloger_list_test.go b/cmd/syft/internal/commands/cataloger_list_test.go index b1a89af35..95c32bd07 100644 --- a/cmd/syft/internal/commands/cataloger_list_test.go +++ b/cmd/syft/internal/commands/cataloger_list_test.go @@ -184,11 +184,11 @@ Default selections: 1 • 'image' Selection expressions: 6 • 'b' (intersect) - • '-directory' (remove) • '-c' (remove) + • '-directory' (remove) • '-file' (remove) - • '+task3' (add) • '+file-task1' (add) + • '+task3' (add) ┌────────────────┬──────────────────┐ │ FILE CATALOGER │ TAGS │ ├────────────────┼──────────────────┤ @@ -200,6 +200,43 @@ Selection expressions: 6 │ task1 │ 1, a, b, image │ │ task3 │ 3, c, d, directory │ └───────────────────┴────────────────────┘ +`, + }, + { + name: "with comma separated expressions, table", + options: func() *catalogerListOptions { + c := defaultCatalogerListOptions() + c.Output = "table" + c.DefaultCatalogers = []string{ + "image,task3,file-task1", + } + c.SelectCatalogers = []string{ + "-task2,c,b", + } + return c + }(), + want: ` +Default selections: 4 + • 'file-task1' + • 'image' + • 'task3' + • 'file' +Selection expressions: 3 + • 'b' (intersect) + • 'c' (intersect) + • '-task2' (remove) +┌────────────────┬──────────────────┐ +│ FILE CATALOGER │ TAGS │ +├────────────────┼──────────────────┤ +│ file-task1 │ file, ft, ft-1-b │ +│ file-task2 │ file, ft, ft-2-b │ +└────────────────┴──────────────────┘ +┌───────────────────┬────────────────────┐ +│ PACKAGE CATALOGER │ TAGS │ +├───────────────────┼────────────────────┤ +│ task1 │ 1, a, b, image │ +│ task3 │ 3, c, d, directory │ +└───────────────────┴────────────────────┘ `, }, { @@ -219,7 +256,7 @@ Selection expressions: 6 return c }(), want: ` -{"default":["image"],"selection":["-directory","+task3","-c","b"],"catalogers":[{"name":"file-task1","tags":["file"]},{"name":"file-task2","tags":["file"]},{"name":"task1","tags":["b","image"]},{"name":"task3","tags":["task3"]}]} +{"default":["image"],"selection":["+task3","-c","-directory","b"],"catalogers":[{"name":"file-task1","tags":["file"]},{"name":"file-task2","tags":["file"]},{"name":"task1","tags":["b","image"]},{"name":"task3","tags":["task3"]}]} `, }, } diff --git a/cmd/syft/internal/options/catalog.go b/cmd/syft/internal/options/catalog.go index 5e2901bcb..b66ce181a 100644 --- a/cmd/syft/internal/options/catalog.go +++ b/cmd/syft/internal/options/catalog.go @@ -272,12 +272,12 @@ func (cfg *Catalog) PostLoad() error { return fmt.Errorf("cannot use both 'catalogers' and 'select-catalogers'/'default-catalogers' flags") } - cfg.From = flatten(cfg.From) + cfg.From = Flatten(cfg.From) - cfg.Catalogers = flatten(cfg.Catalogers) - cfg.DefaultCatalogers = flatten(cfg.DefaultCatalogers) - cfg.SelectCatalogers = flatten(cfg.SelectCatalogers) - cfg.Enrich = flatten(cfg.Enrich) + cfg.Catalogers = Flatten(cfg.Catalogers) + cfg.DefaultCatalogers = Flatten(cfg.DefaultCatalogers) + cfg.SelectCatalogers = Flatten(cfg.SelectCatalogers) + cfg.Enrich = Flatten(cfg.Enrich) // for backwards compatibility cfg.DefaultCatalogers = append(cfg.DefaultCatalogers, cfg.Catalogers...) @@ -295,7 +295,7 @@ func (cfg *Catalog) PostLoad() error { return nil } -func flatten(commaSeparatedEntries []string) []string { +func Flatten(commaSeparatedEntries []string) []string { var out []string for _, v := range commaSeparatedEntries { for _, s := range strings.Split(v, ",") { diff --git a/cmd/syft/internal/options/catalog_test.go b/cmd/syft/internal/options/catalog_test.go index 89527cb3f..d74931be1 100644 --- a/cmd/syft/internal/options/catalog_test.go +++ b/cmd/syft/internal/options/catalog_test.go @@ -139,7 +139,7 @@ func Test_enrichmentEnabled(t *testing.T) { for _, test := range tests { t.Run(test.directives, func(t *testing.T) { - got := enrichmentEnabled(flatten([]string{test.directives}), test.test) + got := enrichmentEnabled(Flatten([]string{test.directives}), test.test) assert.Equal(t, test.expected, got) }) }