use crate::runtime::env::EnvMap;
use anyhow::{Context, Result};
use std::path::PathBuf;
use std::process::Command;
pub fn exec_cargo(subcommand: &str, args: &[String], extra_env: &EnvMap) -> Result<()> {
let mut cmd = Command::new("cargo");
cmd.arg(subcommand).args(args);
if let Some(cargo_path) = resolve_cargo_path() {
cmd.env("CARGO", cargo_path);
}
for (k, _) in std::env::vars_os() {
#[allow(clippy::collapsible_if)]
if let Some(key) = k.to_str() {
if key.starts_with("CARGO_") || key == "CARGO" || key == "MAKEFLAGS" || key == "MFLAGS"
{
cmd.env_remove(key);
}
}
}
for (k, v) in extra_env {
cmd.env(k, v);
}
cmd.stdin(std::process::Stdio::inherit());
cmd.stdout(std::process::Stdio::inherit());
cmd.stderr(std::process::Stdio::inherit());
let status = cmd.status().context("failed to spawn cargo")?;
std::process::exit(status.code().unwrap_or(1));
}
fn resolve_cargo_path() -> Option<PathBuf> {
if let Some(path) = std::env::var_os("CARGO") {
let path = PathBuf::from(path);
if path.is_file() {
return Some(path);
}
}
which::which("cargo").ok()
}