forked from Gitlink/gitlink-cli
78 lines
1.7 KiB
Go
78 lines
1.7 KiB
Go
package compliance
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/gitlink-org/gitlink-cli/internal/output"
|
|
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
|
)
|
|
|
|
// summary holds aggregated stats.
|
|
type summary struct {
|
|
Total int `json:"total"`
|
|
Critical int `json:"critical"`
|
|
High int `json:"high"`
|
|
Medium int `json:"medium"`
|
|
Low int `json:"low"`
|
|
}
|
|
|
|
type reportData struct {
|
|
Modules []string `json:"modules"`
|
|
Findings []Finding `json:"findings"`
|
|
Summary summary `json:"summary"`
|
|
}
|
|
|
|
func outputReport(ctx *common.RuntimeContext, findings []Finding, modules []string) error {
|
|
s := summary{}
|
|
for _, f := range findings {
|
|
s.Total++
|
|
switch f.Severity {
|
|
case "critical": s.Critical++
|
|
case "high": s.High++
|
|
case "medium": s.Medium++
|
|
case "low": s.Low++
|
|
}
|
|
}
|
|
|
|
if ctx.Format == "json" {
|
|
return ctx.OutputData(reportData{Modules: modules, Findings: findings, Summary: s})
|
|
}
|
|
|
|
// human-readable output
|
|
fmt.Println()
|
|
printHR()
|
|
fmt.Printf(" Compliance Scan Report\n")
|
|
fmt.Printf(" Modules: %s | Findings: %d (critical:%d high:%d medium:%d low:%d)\n",
|
|
strings.Join(modules, ", "), s.Total, s.Critical, s.High, s.Medium, s.Low)
|
|
printHR()
|
|
|
|
if len(findings) == 0 {
|
|
fmt.Println(" All clear — no issues found.")
|
|
} else {
|
|
printFindings(findings)
|
|
}
|
|
printHR()
|
|
return nil
|
|
}
|
|
|
|
func printHR() {
|
|
fmt.Println(strings.Repeat("─", 60))
|
|
}
|
|
|
|
func printFindings(findings []Finding) {
|
|
labels := map[string]string{
|
|
"critical": "CRIT", "high": "HIGH", "medium": "MED", "low": "LOW",
|
|
}
|
|
for _, f := range findings {
|
|
label := labels[f.Severity]
|
|
if label == "" {
|
|
label = f.Severity
|
|
}
|
|
fmt.Printf(" [%s] %s %s:%d %s\n", label, f.ID, f.File, f.Line, f.Summary)
|
|
}
|
|
}
|
|
|
|
// Ensure output import is used
|
|
var _ = output.SuccessEnvelope
|