///|
/// Severity level for a project health diagnostic.
pub(all) enum Severity {
Error
Warn
Info
} derive(Debug, Eq)
///|
pub fn Severity::label(self : Severity) -> String {
match self {
Error => "ERROR"
Warn => "WARN"
Info => "INFO"
}
}
///|
/// Quality area that owns a release-readiness rule.
pub(all) enum RuleCategory {
Manifest
Package
Documentation
Ci
Release
} derive(Debug, Eq)
///|
pub fn RuleCategory::label(self : RuleCategory) -> String {
match self {
Manifest => "manifest"
Package => "package"
Documentation => "documentation"
Ci => "ci"
Release => "release"
}
}
///|
/// Source location attached to a diagnostic when a parser can identify it.
pub(all) struct SourceLocation {
path : String
line : Int
column : Int
} derive(Debug, Eq)
///|
pub fn SourceLocation::new(
path : String,
line : Int,
column : Int,
) -> SourceLocation {
{ path, line, column }
}
///|
/// Stable metadata for an explainable Moon Doctor rule.
pub(all) struct RuleDefinition {
id : String
category : RuleCategory
default_severity : Severity
title : String
description : String
remediation : String
profiles : Array[String]
} derive(Debug, Eq)
///|
pub fn RuleDefinition::new(
id : String,
category : RuleCategory,
default_severity : Severity,
title : String,
description : String,
remediation : String,
profiles : Array[String],
) -> RuleDefinition {
{ id, category, default_severity, title, description, remediation, profiles }
}
///|
/// One finding produced by Moon Doctor.
pub(all) struct Diagnostic {
severity : Severity
code : String
message : String
detail : String
location : SourceLocation?
remediation : Array[String]
} derive(Debug, Eq)
///|
pub fn Diagnostic::new(
severity : Severity,
code : String,
message : String,
detail : String,
) -> Diagnostic {
{ severity, code, message, detail, location: None, remediation: [] }
}
///|
pub fn Diagnostic::at(
severity : Severity,
code : String,
message : String,
detail : String,
location : SourceLocation,
remediation : Array[String],
) -> Diagnostic {
{ severity, code, message, detail, location: Some(location), remediation }
}
///|
/// Final score summary for a diagnostic run.
pub(all) struct Score {
grade : String
status : String
errors : Int
warnings : Int
infos : Int
} derive(Debug, Eq)
///|
pub fn Score::from_diagnostics(diagnostics : Array[Diagnostic]) -> Score {
let mut errors = 0
let mut warnings = 0
let mut infos = 0
for item in diagnostics {
match item.severity {
Error => errors += 1
Warn => warnings += 1
Info => infos += 1
}
}
let (grade, status) = if errors > 0 {
("D", "fail")
} else if warnings >= 3 {
("C", "warn")
} else if warnings > 0 {
("B", "warn")
} else {
("A", "pass")
}
{ grade, status, errors, warnings, infos }
}
///|
/// Complete report data before rendering.
pub(all) struct DoctorReport {
root : String
diagnostics : Array[Diagnostic]
score : Score
profile : String
checklist : Array[String]
} derive(Debug, Eq)
///|
pub fn DoctorReport::new(
root : String,
diagnostics : Array[Diagnostic],
) -> DoctorReport {
{
root,
diagnostics,
score: Score::from_diagnostics(diagnostics),
profile: "default",
checklist: default_release_checklist(),
}
}
///|
pub fn DoctorReport::with_context(
root : String,
diagnostics : Array[Diagnostic],
profile : String,
checklist : Array[String],
) -> DoctorReport {
{
root,
diagnostics,
score: Score::from_diagnostics(diagnostics),
profile,
checklist,
}
}
///|
pub fn DoctorReport::conclusion(self : DoctorReport) -> String {
if self.score.errors > 0 || self.score.warnings > 0 {
"Needs work"
} else {
"Ready for GitHub"
}
}
///|
pub fn default_release_checklist() -> Array[String] {
[
"Review README.md and LICENSE", "Run moon check", "Run moon test", "Run moon package before publishing to mooncakes",
"Push the repository with the prepared Git history",
]
}