///|
fn sarif_level(severity : Severity) -> String {
match severity {
Error => "error"
Warn => "warning"
Info => "note"
}
}
///|
fn sarif_rule(rule : RuleDefinition) -> Json {
Json::object({
"id": Json::string(rule.id),
"name": Json::string(rule.id),
"shortDescription": Json::object({ "text": Json::string(rule.title) }),
"fullDescription": Json::object({ "text": Json::string(rule.description) }),
"help": Json::object({ "text": Json::string(rule.remediation) }),
"properties": Json::object({
"category": Json::string(rule.category.label()),
"defaultSeverity": Json::string(rule.default_severity.label()),
}),
})
}
///|
fn sarif_region(location : SourceLocation) -> Json {
Json::object({
"startLine": Json::number(location.line.to_double()),
"startColumn": Json::number(location.column.to_double()),
})
}
///|
fn sarif_location(location : SourceLocation) -> Json {
Json::object({
"physicalLocation": Json::object({
"artifactLocation": Json::object({ "uri": Json::string(location.path) }),
"region": sarif_region(location),
}),
})
}
///|
fn sarif_fix(diagnostic : Diagnostic) -> Json? {
if diagnostic.remediation.length() == 0 {
None
} else {
Some(
Json::object({
"description": Json::object({
"text": Json::string(diagnostic.remediation.join(" ")),
}),
}),
)
}
}
///|
fn sarif_result(diagnostic : Diagnostic) -> Json {
let locations = match diagnostic.location {
Some(location) => [sarif_location(location)]
None => []
}
let result : Map[String, Json] = {
"ruleId": Json::string(diagnostic.code),
"level": Json::string(sarif_level(diagnostic.severity)),
"message": Json::object({
"text": Json::string(diagnostic.message + ": " + diagnostic.detail),
}),
"locations": Json::array(locations),
}
match sarif_fix(diagnostic) {
Some(fix) => result["fixes"] = Json::array([fix])
None => ()
}
Json::object(result)
}
///|
fn sarif_driver() -> Json {
Json::object({
"name": Json::string("Moon Doctor"),
"informationUri": Json::string(
"https://github.com/sheldonshi115/moon-doctor",
),
"rules": Json::array(rule_catalog().map(sarif_rule)),
})
}
///|
/// Render a deterministic SARIF 2.1.0 document for GitHub Code Scanning.
pub fn render_sarif_report(report : DoctorReport) -> String {
let document = Json::object({
"$schema": Json::string("https://json.schemastore.org/sarif-2.1.0.json"),
"version": Json::string("2.1.0"),
"runs": Json::array([
Json::object({
"tool": Json::object({ "driver": sarif_driver() }),
"results": Json::array(report.diagnostics.map(sarif_result)),
"properties": Json::object({
"project": Json::string(report.root),
"profile": Json::string(report.profile),
"conclusion": Json::string(report.conclusion()),
}),
}),
]),
})
document.stringify()
}