use std::path::Path;
use std::process::Command;
pub fn is_in_container() -> bool {
Path::new("/.dockerenv").exists()
|| Path::new("/run/.containerenv").exists()
|| std::env::var("container").is_ok()
}
pub fn find_workspace_root() -> Result<std::path::PathBuf, String> {
let mut current = std::env::current_dir()
.map_err(|e| format!("Failed to get current directory: {}", e))?;
loop {
if current.join(".git").exists() {
return Ok(current);
}
let cargo_toml = current.join("Cargo.toml");
if cargo_toml.exists() {
if let Ok(content) = std::fs::read_to_string(&cargo_toml) {
if content.contains("[workspace]") {
return Ok(current);
}
}
}
if !current.pop() {
break;
}
}
std::env::current_dir()
.map_err(|e| format!("Failed to get current directory: {}", e))
}
pub fn ensure_container() -> Result<std::path::PathBuf, String> {
let workspace_root = find_workspace_root()?;
let output = Command::new("podman")
.args(["ps", "--filter", "name=gametank", "--filter", "status=running", "--format", "{{.Names}}"])
.output()
.map_err(|e| format!("Failed to check container status: {}", e))?;
let stdout = String::from_utf8_lossy(&output.stdout);
if stdout.contains("gametank") {
return Ok(workspace_root);
}
println!("Starting build container...");
let status = Command::new("podman")
.args([
"run", "-d",
"--name", "gametank",
"-v", &format!("{}:/workspace:z", workspace_root.display()),
"--replace",
"rust-mos:gte",
"sleep", "infinity"
])
.status()
.map_err(|e| format!("Failed to start container: {}", e))?;
if status.success() {
Ok(workspace_root)
} else {
Err("Failed to start build container".to_string())
}
}
pub fn podman_exec(workdir: &str, args: &[&str]) -> Result<(), String> {
let status = Command::new("podman")
.args(["exec", "-t", "-w", workdir, "gametank"])
.args(args)
.status()
.map_err(|e| format!("Failed to exec in container: {}", e))?;
if status.success() {
Ok(())
} else {
Err(format!("Command failed: {:?}", args))
}
}