use std::process::Command;
pub fn isolate_host(command: &mut Command) -> &mut Command {
scrub_settings(command);
#[cfg(unix)]
{
let real_home = std::env::var_os("HOME").map(std::path::PathBuf::from);
for (name, default) in [("CARGO_HOME", ".cargo"), ("RUSTUP_HOME", ".rustup")] {
let value = std::env::var_os(name)
.map(std::path::PathBuf::from)
.or_else(|| real_home.as_ref().map(|home| home.join(default)));
if let Some(value) = value {
command.env(name, value);
}
}
let home = isolated_home();
command
.env("HOME", home)
.env("XDG_CACHE_HOME", home.join(".cache"))
.env("XDG_CONFIG_HOME", home.join(".config"))
.env("XDG_DATA_HOME", home.join(".local/share"));
}
command
}
fn scrub_settings(command: &mut Command) {
for (name, _) in std::env::vars_os() {
let key = name.to_string_lossy().to_ascii_uppercase();
if key.starts_with("MBX_") && key != "MBX_LOG" {
command.env_remove(&name);
}
}
}
#[cfg(unix)]
fn isolated_home() -> &'static std::path::Path {
static HOME: std::sync::OnceLock<std::path::PathBuf> = std::sync::OnceLock::new();
HOME.get_or_init(|| {
let home = std::path::Path::new(env!("CARGO_TARGET_TMPDIR")).join("isolated-home");
std::fs::create_dir_all(&home).unwrap();
home
})
}