use std::path::Path;
use std::process::{Command, Stdio};
const ENGINES: &[&str] = &["docker", "podman"];
pub fn engine() -> Option<&'static str> {
ENGINES.iter().copied().find(|&e| is_available(e))
}
pub fn available() -> bool {
engine().is_some()
}
fn is_available(tool: &str) -> bool {
Command::new(tool)
.arg("--version")
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
pub fn wrap_command(cmd: &str, image: &str, root: &Path) -> Option<String> {
let engine = engine()?;
let mount = mount_path(root);
let inner = cmd.replace('\'', "'\\''");
Some(format!(
"{engine} run --rm -v \"{mount}:/workspace\" -w /workspace {image} sh -c '{inner}'"
))
}
fn mount_path(root: &Path) -> String {
let s = root.display().to_string();
if cfg!(windows) {
s.replace('\\', "/")
} else {
s
}
}