use crate::doctor::{self, CHROME_INSTALL};
use crate::error::CliError;
use crate::project::App;
pub fn doctor() -> Result<(), CliError> {
let mut problems = 0_usize;
println!("toolchain:");
for tool in doctor::ALL_TOOLS {
match doctor::probe(tool) {
Ok(version) => {
println!(" {:<24} ok {version}", label(tool));
}
Err(failure) => {
problems += 1;
println!(" {:<24} MISSING {failure}", label(tool));
println!(" {} — install: {}", tool.purpose, tool.install);
}
}
}
match doctor::require_chrome() {
Ok(path) => println!(
" {:<24} ok {}",
"Chrome (browser proof)",
path.display()
),
Err(_reason) => {
problems += 1;
println!(
" {:<24} MISSING no installed browser found",
"Chrome (browser proof)"
);
println!(
" drives frame test's real-browser proof — install: {CHROME_INSTALL} (or set CHROME_BIN)"
);
}
}
println!();
match App::find_from_current_dir() {
Ok(app) => {
println!("application at {}:", app.root.display());
match app.load_config() {
Ok(_config) => println!(" frame.toml ok"),
Err(error) => {
problems += 1;
println!(" frame.toml INVALID {error}");
let mut source = std::error::Error::source(&error);
while let Some(cause) = source {
println!(" caused by: {cause}");
source = cause.source();
}
}
}
if app.page_toolchain_installed() {
println!(" page toolchain ok page/node_modules present");
} else {
println!(
" page toolchain not installed — frame check and frame test run \
`npm install` for you (network, once); frame run does not need it"
);
}
match app.stale_page_sources() {
Ok(stale) if stale.is_empty() => {
println!(" compiled page ok current with page/src");
}
Ok(stale) => {
println!(
" compiled page stale {} changed source(s) — frame run \
and frame build recompile it",
stale.len()
);
}
Err(error) => {
problems += 1;
println!(" compiled page UNREADABLE {error}");
}
}
}
Err(CliError::NotAnApplication { .. }) => {
println!("no application here (no frame.toml in this directory or any parent);");
println!("toolchain checks above are the whole report. `frame new my_app` starts one.");
}
Err(other) => return Err(other),
}
if problems == 0 {
println!();
println!("frame doctor: everything present");
Ok(())
} else {
Err(CliError::DoctorProblems { problems })
}
}
fn label(tool: &doctor::Tool) -> String {
format!("{} ({})", tool.name, tool.command)
}