use std::env;
use std::path::PathBuf;
use std::process::Command;
use anyhow::Context;
use crate::check::dylib::prepend_dylib_path;
use crate::check::{driver_path, preflight, sysroot};
use crate::config::{
CHECK_TARGET_DIR, DRIVER_BIN, NO_MANAGE_ENV, RUSTUP_TOOLCHAIN_ENV, SYSROOT_ENV,
};
use crate::toolchain::pinned_toolchain;
pub fn run_check(forwarded_args: &[String]) -> anyhow::Result<i32> {
let managed = env::var_os(NO_MANAGE_ENV).is_none();
let driver = driver_path(DRIVER_BIN)?;
let (sysroot, toolchain) = if managed {
let toolchain = pinned_toolchain();
let sysroot = preflight::run(&driver, &toolchain)?;
(sysroot, Some(toolchain))
} else {
let rustc = env::var("RUSTC").unwrap_or_else(|_| "rustc".to_owned());
(sysroot(&rustc, None)?, None)
};
let mut command = Command::new("cargo");
command.arg("check").args(forwarded_args);
command.env("RUSTC_WORKSPACE_WRAPPER", &driver);
command.env(SYSROOT_ENV, &sysroot);
prepend_dylib_path(&mut command, &sysroot.join("lib"));
if let Some(toolchain) = &toolchain {
command.env(RUSTUP_TOOLCHAIN_ENV, toolchain);
}
inject_target_dir(&mut command, forwarded_args);
let status = command
.status()
.context("failed to run `cargo check` (is cargo on PATH?)")?;
Ok(status.code().unwrap_or(1))
}
fn inject_target_dir(command: &mut Command, forwarded_args: &[String]) {
if env::var_os("CARGO_TARGET_DIR").is_some() || forwards_target_dir(forwarded_args) {
return;
}
command
.arg("--target-dir")
.arg(PathBuf::from(CHECK_TARGET_DIR));
}
pub fn forwards_target_dir(args: &[String]) -> bool {
args.iter()
.any(|arg| arg == "--target-dir" || arg.starts_with("--target-dir="))
}