From e3a04e0ae9eb2d6705a49e2f75ea906941a329c9 Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Tue, 30 Jun 2026 14:28:59 +0300 Subject: [PATCH 1/2] exporting results in table format in frogbot - V3 --- scanpullrequest/scanpullrequest.go | 1 + scanpullrequest/scanpullrequest_test.go | 48 +++++++++++++++++++++++++ scanrepository/scanrepository.go | 1 + scanrepository/scanrepository_test.go | 48 +++++++++++++++++++++++++ utils/utils.go | 13 +++++++ 5 files changed, 111 insertions(+) diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go index 286acb511..b8805493f 100644 --- a/scanpullrequest/scanpullrequest.go +++ b/scanpullrequest/scanpullrequest.go @@ -166,6 +166,7 @@ func auditPullRequestSourceCode(repoConfig *utils.Repository, scanDetails *utils issuesCollection = &issues.ScansIssuesCollection{ScanStatus: getResultScanStatues(scanResults)} return } + utils.PrintScanResultsTable(scanResults) // Set JAS output flags based on the scan results repoConfig.OutputWriter.SetJasOutputFlags(scanResults.Entitlements.Jas, scanResults.HasJasScansResults(jasutils.Applicability)) filterFailedResultsIfScannersFailuresAreAllowed(scanDetails.ResultsToCompare, scanResults, repoConfig.Params.ConfigProfile.GeneralConfig.FailUponAnyScannerError, sourceBranchWd, targetBranchWd) diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index a8c8932b6..06fd05017 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -1505,3 +1505,51 @@ func createSecurityCommandResultsForTest(targetLocation string, targetName strin return result } + +func TestPrintScanResultsTable(t *testing.T) { + tests := []struct { + name string + scanResults *results.SecurityCommandResults + }{ + { + name: "nil scan results should not panic", + scanResults: nil, + }, + { + name: "empty scan results should not panic", + scanResults: &results.SecurityCommandResults{ + Targets: []*results.TargetResults{}, + }, + }, + { + name: "scan results with vulnerabilities should print without error", + scanResults: &results.SecurityCommandResults{ + ResultsMetaData: results.ResultsMetaData{ + ResultContext: results.ResultContext{IncludeVulnerabilities: true}, + }, + Targets: []*results.TargetResults{{ + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{ + DeprecatedXrayResults: []services.ScanResponse{{ + Vulnerabilities: []services.Vulnerability{ + { + Cves: []services.Cve{{Id: "CVE-2022-0001"}}, + Severity: "High", + Components: map[string]services.Component{"test-dep:1.0.0": {FixedVersions: []string{"1.0.1"}}}, + }, + }, + }}, + }, + }}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.NotPanics(t, func() { + utils.PrintScanResultsTable(test.scanResults) + }) + }) + } +} diff --git a/scanrepository/scanrepository.go b/scanrepository/scanrepository.go index 0847e1d9a..de87ba791 100644 --- a/scanrepository/scanrepository.go +++ b/scanrepository/scanrepository.go @@ -160,6 +160,7 @@ func (sr *ScanRepositoryCmd) scanAndFixBranch(repository *utils.Repository) (tot // Always check policy even if an error occurred during the scan err = errors.Join(err, policy.CheckPolicyFailBuildError(scanResults)) }() + utils.PrintScanResultsTable(scanResults) totalFindings = getTotalFindingsFromScanResults(scanResults) sr.uploadResultsToGithubDashboardsIfNeeded(repository, scanResults) sr.uploadGitLabScanResultsIfNeeded(repository, scanResults) diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go index ec8b6ec27..37325efc0 100644 --- a/scanrepository/scanrepository_test.go +++ b/scanrepository/scanrepository_test.go @@ -1061,3 +1061,51 @@ func createTestConfigProfile(aggregateFixes, failUponAnyScannerError bool) servi }}, } } + +func TestPrintScanResultsTable(t *testing.T) { + tests := []struct { + name string + scanResults *results.SecurityCommandResults + }{ + { + name: "nil scan results should not panic", + scanResults: nil, + }, + { + name: "empty scan results should not panic", + scanResults: &results.SecurityCommandResults{ + Targets: []*results.TargetResults{}, + }, + }, + { + name: "scan results with vulnerabilities should print without error", + scanResults: &results.SecurityCommandResults{ + ResultsMetaData: results.ResultsMetaData{ + ResultContext: results.ResultContext{IncludeVulnerabilities: true}, + }, + Targets: []*results.TargetResults{{ + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{ + DeprecatedXrayResults: []services.ScanResponse{{ + Vulnerabilities: []services.Vulnerability{ + { + Cves: []services.Cve{{Id: "CVE-2022-0001"}}, + Severity: "High", + Components: map[string]services.Component{"test-dep:1.0.0": {FixedVersions: []string{"1.0.1"}}}, + }, + }, + }}, + }, + }}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.NotPanics(t, func() { + utils.PrintScanResultsTable(test.scanResults) + }) + }) + } +} diff --git a/utils/utils.go b/utils/utils.go index 10414147d..f6406ec0c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -18,6 +18,7 @@ import ( "github.com/jfrog/froggit-go/vcsclient" "github.com/jfrog/gofrog/version" "github.com/jfrog/jfrog-cli-core/v2/common/commands" + "github.com/jfrog/jfrog-cli-core/v2/common/format" "github.com/jfrog/jfrog-cli-core/v2/utils/config" "github.com/jfrog/jfrog-cli-security/utils" "github.com/jfrog/jfrog-cli-security/utils/formats" @@ -516,3 +517,15 @@ func writeCycloneDxToDir(outputDir string, scanResults *results.SecurityCommandR log.Info(fmt.Sprintf("CycloneDX SBOM written to %s", path)) return nil } + +func PrintScanResultsTable(scanResults *results.SecurityCommandResults) { + if scanResults == nil { + return + } + if err := output.NewResultsWriter(scanResults). + SetOutputFormat(format.Table). + SetPrintExtendedTable(true). + PrintScanResults(); err != nil { + log.Warn(fmt.Sprintf("Failed to print scan results table: %s", err.Error())) + } +} From 0091034cb39fe26cf152f3203b1144ea8e8a8b05 Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Mon, 6 Jul 2026 10:56:37 +0300 Subject: [PATCH 2/2] fix cr notes --- scanpullrequest/scanpullrequest_test.go | 48 ------------------------ scanrepository/scanrepository_test.go | 48 ------------------------ utils/utils.go | 1 - utils/utils_test.go | 49 +++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 97 deletions(-) diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index 06fd05017..a8c8932b6 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -1505,51 +1505,3 @@ func createSecurityCommandResultsForTest(targetLocation string, targetName strin return result } - -func TestPrintScanResultsTable(t *testing.T) { - tests := []struct { - name string - scanResults *results.SecurityCommandResults - }{ - { - name: "nil scan results should not panic", - scanResults: nil, - }, - { - name: "empty scan results should not panic", - scanResults: &results.SecurityCommandResults{ - Targets: []*results.TargetResults{}, - }, - }, - { - name: "scan results with vulnerabilities should print without error", - scanResults: &results.SecurityCommandResults{ - ResultsMetaData: results.ResultsMetaData{ - ResultContext: results.ResultContext{IncludeVulnerabilities: true}, - }, - Targets: []*results.TargetResults{{ - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - DeprecatedXrayResults: []services.ScanResponse{{ - Vulnerabilities: []services.Vulnerability{ - { - Cves: []services.Cve{{Id: "CVE-2022-0001"}}, - Severity: "High", - Components: map[string]services.Component{"test-dep:1.0.0": {FixedVersions: []string{"1.0.1"}}}, - }, - }, - }}, - }, - }}, - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.NotPanics(t, func() { - utils.PrintScanResultsTable(test.scanResults) - }) - }) - } -} diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go index 37325efc0..ec8b6ec27 100644 --- a/scanrepository/scanrepository_test.go +++ b/scanrepository/scanrepository_test.go @@ -1061,51 +1061,3 @@ func createTestConfigProfile(aggregateFixes, failUponAnyScannerError bool) servi }}, } } - -func TestPrintScanResultsTable(t *testing.T) { - tests := []struct { - name string - scanResults *results.SecurityCommandResults - }{ - { - name: "nil scan results should not panic", - scanResults: nil, - }, - { - name: "empty scan results should not panic", - scanResults: &results.SecurityCommandResults{ - Targets: []*results.TargetResults{}, - }, - }, - { - name: "scan results with vulnerabilities should print without error", - scanResults: &results.SecurityCommandResults{ - ResultsMetaData: results.ResultsMetaData{ - ResultContext: results.ResultContext{IncludeVulnerabilities: true}, - }, - Targets: []*results.TargetResults{{ - ScanTarget: results.ScanTarget{Target: "test-target"}, - ScaResults: &results.ScaScanResults{ - DeprecatedXrayResults: []services.ScanResponse{{ - Vulnerabilities: []services.Vulnerability{ - { - Cves: []services.Cve{{Id: "CVE-2022-0001"}}, - Severity: "High", - Components: map[string]services.Component{"test-dep:1.0.0": {FixedVersions: []string{"1.0.1"}}}, - }, - }, - }}, - }, - }}, - }, - }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - assert.NotPanics(t, func() { - utils.PrintScanResultsTable(test.scanResults) - }) - }) - } -} diff --git a/utils/utils.go b/utils/utils.go index f6406ec0c..fe385cdc1 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -524,7 +524,6 @@ func PrintScanResultsTable(scanResults *results.SecurityCommandResults) { } if err := output.NewResultsWriter(scanResults). SetOutputFormat(format.Table). - SetPrintExtendedTable(true). PrintScanResults(); err != nil { log.Warn(fmt.Sprintf("Failed to print scan results table: %s", err.Error())) } diff --git a/utils/utils_test.go b/utils/utils_test.go index 2fc3784f5..4d406f16f 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -2,6 +2,7 @@ package utils import ( "encoding/json" + "github.com/jfrog/jfrog-client-go/xray/services" "net/http/httptest" "os" "path" @@ -635,3 +636,51 @@ func TestWriteScanResultsToGitlabDir(t *testing.T) { }) } } + +func TestPrintScanResultsTable(t *testing.T) { + tests := []struct { + name string + scanResults *results.SecurityCommandResults + }{ + { + name: "nil scan results should not panic", + scanResults: nil, + }, + { + name: "empty scan results should not panic", + scanResults: &results.SecurityCommandResults{ + Targets: []*results.TargetResults{}, + }, + }, + { + name: "scan results with vulnerabilities should print without error", + scanResults: &results.SecurityCommandResults{ + ResultsMetaData: results.ResultsMetaData{ + ResultContext: results.ResultContext{IncludeVulnerabilities: true}, + }, + Targets: []*results.TargetResults{{ + ScanTarget: results.ScanTarget{Target: "test-target"}, + ScaResults: &results.ScaScanResults{ + DeprecatedXrayResults: []services.ScanResponse{{ + Vulnerabilities: []services.Vulnerability{ + { + Cves: []services.Cve{{Id: "CVE-2022-0001"}}, + Severity: "High", + Components: map[string]services.Component{"test-dep:1.0.0": {FixedVersions: []string{"1.0.1"}}}, + }, + }, + }}, + }, + }}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.NotPanics(t, func() { + PrintScanResultsTable(test.scanResults) + }) + }) + } +}