ferro_cli/doctor/checks/
generated_artifacts.rs1use crate::doctor::check::{CheckResult, DoctorCheck};
5use std::path::Path;
6
7pub struct GeneratedArtifactsCheck;
8
9const NAME: &str = "generated_artifacts";
10const ARTIFACTS: &[&str] = &["Dockerfile", ".dockerignore", ".do/app.yaml"];
11
12impl DoctorCheck for GeneratedArtifactsCheck {
13 fn name(&self) -> &'static str {
14 NAME
15 }
16 fn run(&self, root: &Path) -> CheckResult {
17 check_impl(root)
18 }
19}
20
21pub(crate) fn check_impl(root: &Path) -> CheckResult {
22 let missing: Vec<&str> = ARTIFACTS
23 .iter()
24 .filter(|f| !root.join(f).exists())
25 .copied()
26 .collect();
27 if missing.is_empty() {
28 CheckResult::ok(NAME, "Dockerfile, .dockerignore, .do/app.yaml present")
29 } else {
30 CheckResult::warn(NAME, format!("{} artifact(s) missing", missing.len()))
31 .with_details(format!("missing: {}", missing.join(", ")))
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38 use std::fs;
39 use tempfile::TempDir;
40
41 #[test]
42 fn name_is_generated_artifacts() {
43 assert_eq!(GeneratedArtifactsCheck.name(), "generated_artifacts");
44 }
45
46 #[test]
47 fn all_present_returns_ok() {
48 let tmp = TempDir::new().unwrap();
49 fs::write(tmp.path().join("Dockerfile"), "").unwrap();
50 fs::write(tmp.path().join(".dockerignore"), "").unwrap();
51 fs::create_dir(tmp.path().join(".do")).unwrap();
52 fs::write(tmp.path().join(".do/app.yaml"), "").unwrap();
53 let r = check_impl(tmp.path());
54 assert_eq!(r.status, crate::doctor::check::CheckStatus::Ok);
55 }
56
57 #[test]
58 fn missing_warns_never_errors() {
59 let tmp = TempDir::new().unwrap();
60 let r = check_impl(tmp.path());
61 assert_eq!(r.status, crate::doctor::check::CheckStatus::Warn);
62 }
63}