gitlink-cli/shortcuts/compliance/report.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