From 2c1bffec2045f8854c121704ca1e60401dbaee0b Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Tue, 30 Jun 2026 10:44:48 +0300 Subject: [PATCH 1/3] exporting results in table format in frogbot - V2 --- scanpullrequest/scanpullrequest.go | 2 ++ scanpullrequest/scanpullrequest_test.go | 48 +++++++++++++++++++++++++ scanrepository/scanrepository.go | 1 + scanrepository/scanrepository_test.go | 48 +++++++++++++++++++++++++ utils/utils.go | 13 +++++++ 5 files changed, 112 insertions(+) diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go index 5e0863677..dc77b7264 100644 --- a/scanpullrequest/scanpullrequest.go +++ b/scanpullrequest/scanpullrequest.go @@ -325,6 +325,8 @@ func auditPullRequestCode(repoConfig *utils.Repository, scanDetails *utils.ScanD scanResults = aggregatedScanResults } + utils.PrintScanResultsTable(scanResults) + return } diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index 73656a3a6..ba120c0a6 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -1616,6 +1616,54 @@ func intPtr(i int) *int { return &i } +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) + }) + }) + } +} + func createSecurityCommandResultsForTest(targetLocation string, targetName string, withScaResults bool, withCaResults bool, withSecretsResult bool, withIacResults bool, withSastResults bool, withViolations bool, scaStatusCode int, caStatusCode int, secretsStatusCode int, iacStatusCode int, sastStatusCode int, violationsStatusCode int) *results.SecurityCommandResults { targetResults := &results.TargetResults{ ScanTarget: results.ScanTarget{Target: targetLocation, Name: targetName}, diff --git a/scanrepository/scanrepository.go b/scanrepository/scanrepository.go index 111052f04..4deeeb0fe 100644 --- a/scanrepository/scanrepository.go +++ b/scanrepository/scanrepository.go @@ -193,6 +193,7 @@ func (cfp *ScanRepositoryCmd) scanAndFixProject(repository *utils.Repository) (b } continue } + utils.PrintScanResultsTable(scanResults) totalFindings += getTotalFindingsFromScanResults(scanResults) shouldFailBuild = shouldFailBuild || (scanResults.Violations != nil && scanResults.Violations.ShouldFailBuild()) if repository.GitProvider.String() == vcsutils.GitHub.String() { diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go index 072dd3588..de34646f9 100644 --- a/scanrepository/scanrepository_test.go +++ b/scanrepository/scanrepository_test.go @@ -976,3 +976,51 @@ func verifyLockFileDiff(branchToInspect string, lockFiles ...string) (output []b } return } + +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 a62dd3ef9..2e32273c0 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -17,6 +17,7 @@ import ( "github.com/jfrog/gofrog/datastructures" "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-core/v2/utils/usage" "github.com/jfrog/jfrog-cli-security/utils" @@ -590,3 +591,15 @@ func CreateErrorIfPartialResultsDisabled(allowPartial bool, messageForLog string } return err } + +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 2b15a49ad10f7d58887f7d1c6c1e15d6afbcc104 Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Mon, 6 Jul 2026 10:29:09 +0300 Subject: [PATCH 2/3] cr fixes --- scanpullrequest/scanpullrequest.go | 1 - scanrepository/scanrepository_test.go | 48 -------------------------- utils/utils.go | 1 - utils/utils_test.go | 49 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 50 deletions(-) diff --git a/scanpullrequest/scanpullrequest.go b/scanpullrequest/scanpullrequest.go index dc77b7264..a6ee115d6 100644 --- a/scanpullrequest/scanpullrequest.go +++ b/scanpullrequest/scanpullrequest.go @@ -326,7 +326,6 @@ func auditPullRequestCode(repoConfig *utils.Repository, scanDetails *utils.ScanD } utils.PrintScanResultsTable(scanResults) - return } diff --git a/scanrepository/scanrepository_test.go b/scanrepository/scanrepository_test.go index de34646f9..072dd3588 100644 --- a/scanrepository/scanrepository_test.go +++ b/scanrepository/scanrepository_test.go @@ -976,51 +976,3 @@ func verifyLockFileDiff(branchToInspect string, lockFiles ...string) (output []b } return } - -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 2e32273c0..eecf95daf 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -598,7 +598,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 4faf17873..c74f10006 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -1,6 +1,7 @@ package utils import ( + "github.com/jfrog/jfrog-client-go/xray/services" "net/http/httptest" "os" "path" @@ -575,3 +576,51 @@ func createTestSecurityCommandResults() *results.SecurityCommandResults { return scanResults } + +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) + }) + }) + } +} From 1de83a83e23987191168056e8f95e04268b17635 Mon Sep 17 00:00:00 2001 From: Eran Turgeman Date: Mon, 6 Jul 2026 10:57:49 +0300 Subject: [PATCH 3/3] fix cr notes --- scanpullrequest/scanpullrequest_test.go | 48 ------------------------- 1 file changed, 48 deletions(-) diff --git a/scanpullrequest/scanpullrequest_test.go b/scanpullrequest/scanpullrequest_test.go index ba120c0a6..73656a3a6 100644 --- a/scanpullrequest/scanpullrequest_test.go +++ b/scanpullrequest/scanpullrequest_test.go @@ -1616,54 +1616,6 @@ func intPtr(i int) *int { return &i } -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) - }) - }) - } -} - func createSecurityCommandResultsForTest(targetLocation string, targetName string, withScaResults bool, withCaResults bool, withSecretsResult bool, withIacResults bool, withSastResults bool, withViolations bool, scaStatusCode int, caStatusCode int, secretsStatusCode int, iacStatusCode int, sastStatusCode int, violationsStatusCode int) *results.SecurityCommandResults { targetResults := &results.TargetResults{ ScanTarget: results.ScanTarget{Target: targetLocation, Name: targetName},