use std::path::{Path, PathBuf};
use std::process::Command;
use trusty_common::test_harness::REPO_ROOT_ENV;
use super::test_support::repo_root;
const PROBE_ENV: &str = "TRUSTY_TEST_REPO_ROOT_PROBE";
const PREFIX: &str = "REPO_ROOT=";
#[test]
fn repo_root_probe() {
if std::env::var_os(PROBE_ENV).is_none_or(|v| v != "1") {
return;
}
let root = repo_root().canonicalize().expect("canonical repo root");
println!("{PREFIX}{}", root.display());
}
fn fake_checkout(dir: &Path) -> PathBuf {
std::fs::create_dir_all(dir.join("crates/trusty-mpm")).expect("mkdir checkout");
std::fs::write(
dir.join("Cargo.toml"),
"[workspace]\nmembers = [\"crates/*\"]\n",
)
.expect("write workspace manifest");
dir.canonicalize().expect("canonical checkout")
}
fn probe(configure: impl FnOnce(&mut Command)) -> Result<PathBuf, String> {
let module = module_path!()
.split_once("::")
.map_or(module_path!(), |(_, rest)| rest);
let name = format!("{module}::repo_root_probe");
let exe = std::env::current_exe().expect("current test binary");
let mut cmd = Command::new(exe);
cmd.args(["--exact", &name, "--nocapture", "--test-threads=1"])
.env(PROBE_ENV, "1");
configure(&mut cmd);
let out = cmd.output().expect("re-exec the test binary");
let stdout = String::from_utf8_lossy(&out.stdout);
stdout
.lines()
.find_map(|line| line.split_once(PREFIX).map(|(_, root)| root.trim()))
.map(PathBuf::from)
.ok_or_else(|| {
format!(
"probe printed no {PREFIX} line ({}):\nstdout:\n{stdout}\nstderr:\n{}",
out.status,
String::from_utf8_lossy(&out.stderr)
)
})
}
#[test]
fn repo_root_follows_the_runtime_checkout_9298() {
let tmp = tempfile::tempdir().expect("tempdir");
let b = fake_checkout(&tmp.path().join("b"));
let b2 = fake_checkout(&tmp.path().join("b2"));
let member = b.join("crates/trusty-mpm");
let cases: [(&str, Option<&Path>, Option<&Path>, &Path); 3] = [
(
"(i) runtime CARGO_MANIFEST_DIR and cwd name B",
Some(&member),
None,
&b,
),
("(ii) cwd names B, CARGO_MANIFEST_DIR unset", None, None, &b),
(
"(iii) TRUSTY_TEST_REPO_ROOT names B2",
Some(&member),
Some(&b2),
&b2,
),
];
for (name, manifest_dir, explicit, want) in cases {
let got = probe(|cmd| {
cmd.current_dir(&member);
match manifest_dir {
Some(dir) => cmd.env("CARGO_MANIFEST_DIR", dir),
None => cmd.env_remove("CARGO_MANIFEST_DIR"),
};
match explicit {
Some(dir) => cmd.env(REPO_ROOT_ENV, dir),
None => cmd.env_remove(REPO_ROOT_ENV),
};
})
.unwrap_or_else(|e| panic!("{name}: {e}"));
assert_eq!(got, want, "{name}: resolved {}", got.display());
}
}