///|
/// Render a compact human-readable audit report.
pub fn render_text(report : AuditReport) -> String {
let out = StringBuilder::new()
out.write_string("MoonSeal audit: \{report.project.name}\n")
out.write_string("Score: \{report.score}/100\n")
out.write_string(
"Source: \{report.moonbit_source_lines} MoonBit lines | \{report.error_count()} errors | \{report.warning_count()} warnings\n",
)
if report.findings.is_empty() {
out.write_string("\nREADY No release-readiness issues found.\n")
} else {
out.write_string("\n")
for finding in report.findings {
let location = if finding.path.is_empty() {
""
} else {
" [\{finding.path}]"
}
out.write_string(
"\{finding.severity.label()} \{finding.code}\{location}: \{finding.message}\n",
)
}
}
out.to_string()
}
///|
fn finding_json(finding : Finding) -> Json {
{
"severity": finding.severity.label(),
"code": finding.code,
"path": finding.path,
"message": finding.message,
}
}
///|
/// Render a machine-readable report suitable for CI.
pub fn render_json(report : AuditReport, indent? : Int = 2) -> String {
let findings : Array[Json] = report.findings.map(finding_json)
let value : Json = {
"tool": { "name": "MoonSeal", "version": "0.2.1" },
"project": {
"name": report.project.name,
"version": report.project.version,
"license": report.project.license,
"repository": report.project.repository,
},
"summary": {
"ready": report.is_ready(),
"score": report.score,
"errors": report.error_count(),
"warnings": report.warning_count(),
"moonbitSourceLines": report.moonbit_source_lines,
},
"findings": findings,
}
value.stringify(indent~)
}
///|
/// Render an audit report for issue trackers, pull requests, and build
/// summaries.
pub fn render_markdown(report : AuditReport) -> String {
let out = StringBuilder::new()
out.write_string("# MoonSeal audit: `\{report.project.name}`\n\n")
out.write_string(
"- Status: **\{if report.is_ready() { "READY" } else { "BLOCKED" }}**\n",
)
out.write_string("- Score: **\{report.score}/100**\n")
out.write_string("- MoonBit source lines: \{report.moonbit_source_lines}\n")
out.write_string(
"- Findings: \{report.error_count()} errors, \{report.warning_count()} warnings\n",
)
if report.findings.is_empty() {
out.write_string("\nNo release-readiness issues found.\n")
} else {
out.write_string("\n| Severity | Code | Path | Finding |\n")
out.write_string("| --- | --- | --- | --- |\n")
for finding in report.findings {
out.write_string(
"| \{finding.severity.label()} | \{finding.code} | `\{finding.path}` | \{finding.message} |\n",
)
}
}
out.to_string()
}