2026-06-17 21:13:51 +02:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
from .findings import StaticFinding
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def write_markdown_report(findings: list[StaticFinding], path: Path) -> None:
|
|
|
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
lines = ["# OpenUltraSAST Report", "", f"Findings: {len(findings)}", ""]
|
|
|
|
|
if not findings:
|
|
|
|
|
lines.append("No quick-mode findings were emitted.")
|
|
|
|
|
for finding in findings:
|
|
|
|
|
lines.extend(
|
|
|
|
|
[
|
|
|
|
|
f"## {finding.title}",
|
|
|
|
|
"",
|
|
|
|
|
f"- ID: `{finding.finding_id}`",
|
|
|
|
|
f"- Path: `{finding.path}`",
|
|
|
|
|
f"- Line: `{finding.line}`",
|
2026-06-18 07:57:06 +02:00
|
|
|
f"- Function: `{finding.function_name or 'unknown'}`",
|
2026-06-17 21:13:51 +02:00
|
|
|
f"- Severity: `{finding.severity}`",
|
|
|
|
|
f"- Confidence: `{finding.confidence}`",
|
|
|
|
|
f"- Evidence level: `{finding.evidence_level}`",
|
2026-06-18 07:57:06 +02:00
|
|
|
f"- Reachability: `{finding.reachability_status}`",
|
|
|
|
|
f"- Conditions: `{', '.join(finding.reachability_conditions) or 'none'}`",
|
2026-06-17 21:13:51 +02:00
|
|
|
f"- Ranking priority: `{finding.ranking_priority}`",
|
|
|
|
|
f"- Tags: `{', '.join(finding.tags)}`",
|
|
|
|
|
"",
|
|
|
|
|
finding.rationale,
|
|
|
|
|
"",
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
path.write_text("\n".join(lines).rstrip() + "\n")
|