Skip to content

Commit 67257bb

Browse files
authored
chore: add multi-project scan summary to UFM presenter (#574)
1 parent 8706120 commit 67257bb

File tree

3 files changed

+82
-14
lines changed

3 files changed

+82
-14
lines changed

internal/presenters/funcs.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,17 @@ func getDefaultTemplateFuncMap(config configuration.Configuration, ri runtimeinf
344344
return strings.ReplaceAll(str, old, replaceWith)
345345
}
346346
defaultMap["getFindingTypesFromTestResult"] = getFindingTypesFromTestResult
347+
defaultMap["getFindingTypesFromMultipleTestResults"] = getFindingTypesFromMultipleTestResults
347348
defaultMap["getIssuesFromTestResult"] = func(testResults testapi.TestResult, findingType ...testapi.FindingType) []testapi.Issue {
348349
return utils.ValueOf(testapi.GetIssuesFromTestResult(testResults, findingType))
349350
}
351+
defaultMap["getIssuesFromMultipleTestResults"] = func(testResults []testapi.TestResult, findingType ...testapi.FindingType) []testapi.Issue {
352+
var allIssues []testapi.Issue
353+
for _, result := range testResults {
354+
allIssues = append(allIssues, utils.ValueOf(testapi.GetIssuesFromTestResult(result, findingType))...)
355+
}
356+
return allIssues
357+
}
350358
defaultMap["getIssueMetadata"] = func(issue testapi.Issue, key string) interface{} {
351359
value, found := issue.GetData(key)
352360
if !found {
@@ -362,6 +370,12 @@ func getDefaultTemplateFuncMap(config configuration.Configuration, ri runtimeinf
362370
return json_schemas.DEFAULT_SEVERITIES
363371
}
364372
defaultMap["getSummariesFromIssues"] = testapi.GetSummariesFromIssues
373+
defaultMap["newFindingTypeSummary"] = func(ft testapi.FindingType, issues []testapi.Issue) interface{} {
374+
return struct {
375+
FindingType testapi.FindingType
376+
Issues []testapi.Issue
377+
}{FindingType: ft, Issues: issues}
378+
}
365379
defaultMap["getSortedIssuesFromSummary"] = func(summary *testapi.IssueSummary) []testapi.Issue {
366380
if summary == nil {
367381
return []testapi.Issue{}
@@ -532,6 +546,22 @@ func getFindingTypesFromTestResult(testResults testapi.TestResult) []testapi.Fin
532546
return findingTypesList
533547
}
534548

549+
func getFindingTypesFromMultipleTestResults(testResults []testapi.TestResult) []testapi.FindingType {
550+
findingTypes := map[testapi.FindingType]bool{}
551+
for _, result := range testResults {
552+
for _, ft := range getFindingTypesFromTestResult(result) {
553+
findingTypes[ft] = true
554+
}
555+
}
556+
findingTypesList := slices.Collect(maps.Keys(findingTypes))
557+
if len(findingTypesList) == 0 {
558+
return []testapi.FindingType{"no findings type found"}
559+
}
560+
slices.Sort(findingTypesList)
561+
slices.Reverse(findingTypesList)
562+
return findingTypesList
563+
}
564+
535565
func getDefaultFindingTypesFromConfig(testResults testapi.TestResult) []testapi.FindingType {
536566
if testResults == nil {
537567
return nil

internal/presenters/templates/ufm.human.tmpl

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,23 @@
7878
{{- template "issueBody" . }}
7979
{{- end }} {{/* end issueDetails */}}
8080

81+
{{- define "findingTypeSummary"}}
82+
{{- $summaries := getSummariesFromIssues .Issues }}
83+
{{- $effectiveSummary := index $summaries "effective" }}
84+
{{- $rawSummary := index $summaries "raw" }}
85+
{{- $ignoredSummary := index $summaries "ignored" }}
86+
{{- $effectiveSeverities := index $effectiveSummary.CountBy "severity" }}
87+
{{- $ignoredSeverities := index $ignoredSummary.CountBy "severity" }}
88+
{{- $totalIssueCount := $rawSummary.Count }}
89+
{{- $openIssueCount := $effectiveSummary.Count }}
90+
{{- $ignoredIssueCount := $ignoredSummary.Count }}
91+
92+
Total {{ convertTypeToIssueName .FindingType | toLowerCase }} issues: {{ $totalIssueCount }}
93+
{{- if gt $totalIssueCount 0}}
94+
Ignored: {{ print $ignoredIssueCount | bold }} [{{- range $severity := getSeverities | reverse }}{{- $ignoredCount := index $ignoredSeverities $severity }}{{- print " " $ignoredCount " " $severity " " | renderInSeverityColor }}{{- end}}]
95+
Open : {{ print $openIssueCount | bold }} [{{- range $severity := getSeverities | reverse }}{{- $countFound := index $effectiveSeverities $severity }}{{- print " " $countFound " " $severity " " | renderInSeverityColor }}{{- end}}]{{- end}}
96+
{{- end }} {{/* end findingTypeSummary */}}
97+
8198
{{- define "testSummary"}}{{ "Test Summary" | bold }}
8299
{{- "\n" }}
83100
{{- $metadata := .GetMetadata }}
@@ -92,20 +109,7 @@
92109

93110
{{- range $findingType := $findingTypes }}
94111
{{- $issuesForType := getIssuesFromTestResult $ $findingType }}
95-
{{- $summaries := getSummariesFromIssues $issuesForType }}
96-
{{- $effectiveSummary := index $summaries "effective" }}
97-
{{- $rawSummary := index $summaries "raw" }}
98-
{{- $ignoredSummary := index $summaries "ignored" }}
99-
{{- $effectiveSeverities := index $effectiveSummary.CountBy "severity" }}
100-
{{- $ignoredSeverities := index $ignoredSummary.CountBy "severity" }}
101-
{{- $totalIssueCount := $rawSummary.Count }}
102-
{{- $openIssueCount := $effectiveSummary.Count }}
103-
{{- $ignoredIssueCount := $ignoredSummary.Count }}
104-
105-
Total {{ convertTypeToIssueName $findingType | toLowerCase }} issues: {{ $totalIssueCount }}
106-
{{- if gt $totalIssueCount 0}}
107-
Ignored: {{ print $ignoredIssueCount | bold }} [{{- range $severity := getSeverities | reverse }}{{- $ignoredCount := index $ignoredSeverities $severity }}{{- print " " $ignoredCount " " $severity " " | renderInSeverityColor }}{{- end}}]
108-
Open : {{ print $openIssueCount | bold }} [{{- range $severity := getSeverities | reverse }}{{- $countFound := index $effectiveSeverities $severity }}{{- print " " $countFound " " $severity " " | renderInSeverityColor }}{{- end}}]{{- end}}
112+
{{- template "findingTypeSummary" (newFindingTypeSummary $findingType $issuesForType) }}
109113
{{- end}}
110114
{{- end }} {{/* end testSummary */}}
111115

@@ -296,6 +300,21 @@ Tested {{ int $dependencyCount }} dependencies for known issues, found {{ len $o
296300
{{- end }}
297301
{{- end }}
298302

303+
{{- define "overallTestSummary"}}{{ "Overall Test Summary" | bold }}
304+
{{- "\n" }}
305+
{{- $findingTypes := getFindingTypesFromMultipleTestResults .TestResults }}
306+
Organization: {{ getValueFromConfig "internal_org_slug" }}
307+
Test type: {{ determineProductNameFromFindingTypes $findingTypes }}
308+
Projects tested: {{ len .TestResults }} projects
309+
310+
{{- range $findingType := $findingTypes }}
311+
{{- $issuesForType := getIssuesFromMultipleTestResults $.TestResults $findingType }}
312+
{{- if gt (len $issuesForType) 0 }}
313+
{{- template "findingTypeSummary" (newFindingTypeSummary $findingType $issuesForType) }}
314+
{{- end }}
315+
{{- end}}
316+
{{- end }} {{/* end overallTestSummary */}}
317+
299318
{{- /* Main template */}}
300319
{{- define "main" }}
301320
{{- $totalResults := len $.TestResults }}
@@ -309,6 +328,12 @@ Tested {{ int $dependencyCount }} dependencies for known issues, found {{ len $o
309328
{{- end }}
310329
{{- end }}
311330

331+
{{- /* Render overall summary for multi-project scans */}}
332+
{{- if gt $totalResults 1 }}
333+
{{- "\n" }}{{- divider }}{{- "\n" }}
334+
{{- box (renderToString "overallTestSummary" $) }}
335+
{{- end }}
336+
312337
{{- /* Show hint if results are filtered */}}
313338
{{- $severityThresholdKey := "severity-threshold"}}
314339
{{- if not (eq (getValueFromConfig $severityThresholdKey) "") }}

internal/presenters/testdata/ufm/multi_project.human.readable

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,19 @@ Tested 23 dependencies for known issues, found 19 issues, 27 vulnerable paths.
743743
│ Open : 19 [ 0 CRITICAL  5 HIGH  10 MEDIUM  4 LOW ] │
744744
╰───────────────────────────────────────────────────────────╯
745745

746+
─────────────────────────────────────────────────────
747+
748+
╭────────────────────────────────────────────────────────────╮
749+
│ Overall Test Summary │
750+
│ │
751+
│ Organization: My Org │
752+
│ Test type: Software Composition Analysis │
753+
│ Projects tested: 7 projects │
754+
│ │
755+
│ Total security issues: 67 │
756+
│ Ignored: 0 [ 0 CRITICAL  0 HIGH  0 MEDIUM  0 LOW ] │
757+
│ Open : 67 [ 0 CRITICAL  19 HIGH  40 MEDIUM  8 LOW ] │
758+
╰────────────────────────────────────────────────────────────╯
746759

747760
💡 Tip
748761

0 commit comments

Comments
 (0)