use std::env;
use std::ffi::OsStr;
use std::process::Command;
use crate::toolchain::{resolve, ToolchainSpec};
pub fn build_command<S: AsRef<OsStr>>(
toolchain: ToolchainSpec,
command: Vec<S>,
) -> anyhow::Result<Command> {
let exe_name = command[0].as_ref();
let is_exe_moon = exe_name == "moon";
let mut bin_dir = toolchain.install_path();
bin_dir.push("bin");
if !bin_dir.exists() {
return Err(anyhow::anyhow!("Toolchain '{toolchain}' is not installed"));
}
let err_msg = anyhow::anyhow!(
"Command '{}' not found in toolchain '{toolchain}'",
exe_name.to_string_lossy()
);
let internal_bin_dir = bin_dir.join("internal");
let paths = env::join_paths([&bin_dir, &internal_bin_dir])
.map_err(|e| anyhow::anyhow!("Failed to build PATH environment variable: {}", e))?;
let exe_resolved = resolve::resolve_exe(exe_name, paths).ok_or(err_msg)?;
let mut cmd = Command::new(&exe_resolved);
cmd.args(&command[1..]);
let spec = std::ffi::OsStr::new(toolchain.as_str());
cmd.env(
"MOONUP_TOOLCHAIN_SPEC",
env::var_os("MOONUP_TOOLCHAIN_SPEC").unwrap_or(spec.into()),
);
if is_exe_moon {
let mut libcore = bin_dir.clone();
libcore.pop();
libcore.push("lib");
libcore.push("core");
cmd.env(
"MOON_CORE_OVERRIDE",
env::var_os("MOON_CORE_OVERRIDE").unwrap_or(libcore.into_os_string()),
);
}
tracing::debug!("build command: {:?}", cmd);
Ok(cmd)
}