use std::path::Path;
use std::time::Instant;
use faucet_core::check::Probe;
pub async fn probe_parent_writable(path: &Path, start: Instant) -> Probe {
let parent = match path.parent() {
Some(p) if !p.as_os_str().is_empty() => p.to_path_buf(),
_ => std::path::PathBuf::from("."),
};
if !tokio::fs::try_exists(&parent).await.unwrap_or(false) {
return Probe::fail_hint(
"io",
start.elapsed(),
format!("parent directory {} does not exist", parent.display()),
format!(
"create the directory {} before running the pipeline",
parent.display()
),
);
}
let probe_path = parent.join(format!(".faucet_doctor_probe-{}", uuid_like()));
match tokio::fs::write(&probe_path, b"").await {
Ok(()) => {
let _ = tokio::fs::remove_file(&probe_path).await;
Probe::pass("io", start.elapsed())
}
Err(e) => Probe::fail_hint(
"io",
start.elapsed(),
format!("cannot write to directory {}: {e}", parent.display()),
"ensure the directory is writable by the current user",
),
}
}
fn uuid_like() -> String {
use std::sync::atomic::{AtomicU64, Ordering};
static COUNTER: AtomicU64 = AtomicU64::new(0);
let n = COUNTER.fetch_add(1, Ordering::Relaxed);
let nanos = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_nanos())
.unwrap_or(0);
format!("{}-{}-{}", std::process::id(), n, nanos)
}