use super::build_script_directives::BuildScriptDirectives;
use super::compiler_resolve::parse_version_parts;
use super::manifest::CargoToml;
use super::types::PlannedCompilationUnit;
use std::collections::HashMap;
use std::path::Path;
pub fn compute_unit_rustc_env(
unit: &PlannedCompilationUnit,
directives: Option<&BuildScriptDirectives>,
jobserver_auth: Option<&str>,
) -> HashMap<String, String> {
let mut env = HashMap::new();
let (major, minor, patch, pre) = parse_version_parts(&unit.version);
let pkg_dir = unit.manifest_path.parent().unwrap_or(Path::new("."));
if let Ok(tc) = std::env::var("RUSTUP_TOOLCHAIN") {
env.insert("RUSTUP_TOOLCHAIN".to_string(), tc);
}
if let Some(auth) = jobserver_auth {
env.insert(
"CARGO_MAKEFLAGS".to_string(),
format!("--jobserver-auth={}", auth),
);
env.insert(
"MAKEFLAGS".to_string(),
format!("--jobserver-auth={}", auth),
);
}
env.insert(
"CARGO_MANIFEST_DIR".to_string(),
pkg_dir.to_string_lossy().to_string(),
);
let cargo_bin = std::env::var("CARGO").unwrap_or_else(|_| "cargo".to_string());
env.insert("CARGO".to_string(), cargo_bin);
env.insert("CARGO_PKG_NAME".to_string(), unit.package_name.clone());
env.insert("CARGO_PKG_VERSION".to_string(), unit.version.clone());
env.insert("CARGO_PKG_VERSION_MAJOR".to_string(), major);
env.insert("CARGO_PKG_VERSION_MINOR".to_string(), minor);
env.insert("CARGO_PKG_VERSION_PATCH".to_string(), patch);
env.insert("CARGO_PKG_VERSION_PRE".to_string(), pre);
env.insert("CARGO_CRATE_NAME".to_string(), unit.target_name.clone());
if unit.kind == "bin" {
env.insert("CARGO_BIN_NAME".to_string(), unit.target_name.clone());
}
if let Ok(pkg_toml) = CargoToml::from_file(&unit.manifest_path) {
if let Some(ref p) = pkg_toml.package {
env.insert(
"CARGO_PKG_DESCRIPTION".to_string(),
p.description.clone().unwrap_or_default(),
);
env.insert(
"CARGO_PKG_HOMEPAGE".to_string(),
p.homepage.clone().unwrap_or_default(),
);
env.insert(
"CARGO_PKG_REPOSITORY".to_string(),
p.repository.clone().unwrap_or_default(),
);
env.insert(
"CARGO_PKG_LICENSE".to_string(),
p.license.clone().unwrap_or_default(),
);
env.insert(
"CARGO_PKG_README".to_string(),
p.readme.clone().unwrap_or_default(),
);
let authors = p.authors.as_deref().unwrap_or(&[]).join(":");
env.insert("CARGO_PKG_AUTHORS".to_string(), authors);
let rv = p.rust_version.as_deref().unwrap_or("");
env.insert("CARGO_PKG_RUST_VERSION".to_string(), rv.to_string());
}
} else {
env.insert("CARGO_PKG_RUST_VERSION".to_string(), String::new());
}
if unit.is_primary {
env.insert("CARGO_PRIMARY_PACKAGE".to_string(), "1".to_string());
}
for feat in &unit.features {
env.insert(
format!("CARGO_FEATURE_{}", feat.to_uppercase().replace('-', "_")),
"1".to_string(),
);
}
env.insert("CARGO_CFG_FEATURE".to_string(), unit.features.join(","));
if let Some(dir) = directives {
if let Some(ref out) = dir.out_dir {
env.insert("OUT_DIR".to_string(), out.to_string_lossy().to_string());
}
for (k, v) in &dir.envs {
env.insert(k.clone(), v.clone());
}
}
env
}
pub fn unit_has_build_script(unit: &PlannedCompilationUnit) -> bool {
let pkg_dir = unit.manifest_path.parent().unwrap_or(Path::new("."));
let pkg_toml = CargoToml::from_file(&unit.manifest_path).unwrap_or_default();
match pkg_toml.package.as_ref().and_then(|p| p.build.as_ref()) {
Some(super::manifest::TomlBuild::Disabled(false)) => false,
Some(super::manifest::TomlBuild::Path(ref rel_p)) => pkg_dir.join(rel_p).is_file(),
_ => pkg_dir.join("build.rs").is_file() || pkg_dir.join("build").join("build.rs").is_file(),
}
}
pub fn apply_test_binary_env(
cmd: &mut std::process::Command,
unit: &PlannedCompilationUnit,
cwd: &Path,
target_dir: Option<&Path>,
release: bool,
) {
let profile_name = if release { "release" } else { "debug" };
let mitts_profile_dir = target_dir
.map(|td| td.join(profile_name))
.unwrap_or_else(|| cwd.join("target").join("mitts").join(profile_name));
let mut set_bin_env = |b_name: &str| {
let mitts_bin = mitts_profile_dir.join(b_name);
let var = format!("CARGO_BIN_EXE_{}", b_name.replace('-', "_"));
cmd.env(var, mitts_bin);
};
let pkg_dir = unit.manifest_path.parent().unwrap_or(Path::new("."));
if let Ok(toml) = CargoToml::from_file(&unit.manifest_path) {
for b in toml.discover_targets(pkg_dir) {
if b.kind == "bin" {
set_bin_env(&b.name);
}
}
}
if unit.is_workspace {
if let Ok(root_toml) = CargoToml::from_file(&cwd.join("Cargo.toml")) {
if let Ok(members) = root_toml.discover_workspace_members(cwd) {
for (_, member_dir) in members {
if let Ok(m_toml) = CargoToml::from_file(&member_dir.join("Cargo.toml")) {
for b in m_toml.discover_targets(&member_dir) {
if b.kind == "bin" {
set_bin_env(&b.name);
}
}
}
}
}
}
}
}