use std::path::PathBuf;
use crate::doctor::check::CheckResult;
use super::Ctx;
const DEPS: &[(&str, &str)] = &[
(
"tmux",
"install tmux via your package manager (e.g. brew install tmux)",
),
(
"git",
"install git via your package manager (e.g. xcode-select --install)",
),
("workmux", "install workmux (see its README)"),
("issuectl", "cargo install issuectl (see its README)"),
];
pub fn check(_ctx: &Ctx) -> Vec<CheckResult> {
DEPS.iter()
.map(|(bin, hint)| {
let id = format!("dep.{bin}");
match find_on_path(bin) {
Some(path) => CheckResult::ok(id, format!("{bin} on PATH at {}", path.display())),
None => CheckResult::fail(id, format!("{bin} not found on PATH"), *hint),
}
})
.collect()
}
fn find_on_path(bin: &str) -> Option<PathBuf> {
let path = std::env::var_os("PATH")?;
for dir in std::env::split_paths(&path) {
let candidate = dir.join(bin);
if is_executable_file(&candidate) {
return Some(candidate);
}
}
None
}
#[cfg(unix)]
fn is_executable_file(path: &std::path::Path) -> bool {
use std::os::unix::fs::PermissionsExt;
match std::fs::metadata(path) {
Ok(meta) => meta.is_file() && (meta.permissions().mode() & 0o111 != 0),
Err(_) => false,
}
}
#[cfg(not(unix))]
fn is_executable_file(path: &std::path::Path) -> bool {
path.is_file()
}