#![cfg(unix)]
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::process::Command;
fn kache_binary() -> &'static str {
env!("CARGO_BIN_EXE_kache")
}
#[test]
fn injected_prefix_map_lands_before_the_double_dash_separator() {
let dir = tempfile::tempdir().unwrap();
let argv_dump = dir.path().join("argv.txt");
let fake = dir.path().join("cc");
fs::write(
&fake,
format!(
"#!/bin/sh\n: > '{dump}'\nfor a in \"$@\"; do printf '%s\\n' \"$a\" >> '{dump}'; done\nexit 0\n",
dump = argv_dump.display()
),
)
.unwrap();
fs::set_permissions(&fake, fs::Permissions::from_mode(0o755)).unwrap();
let source = dir.path().join("windows.c");
fs::write(&source, b"int main(void){return 0;}\n").unwrap();
let cache_dir = dir.path().join("cache");
let config = dir.path().join("kache.toml");
let output = Command::new(kache_binary())
.args([
fake.to_str().unwrap(),
"-c",
"-o",
"windows.o",
"--",
source.to_str().unwrap(),
])
.current_dir(dir.path())
.env("KACHE_CACHE_DIR", &cache_dir)
.env("KACHE_CONFIG", &config)
.env("KACHE_BASE_DIR", dir.path())
.env("KACHE_LOG", "kache=debug")
.output()
.expect("failed to run kache as a cc wrapper");
assert!(
output.status.success(),
"kache cc passthrough should succeed; status={:?}\nstderr={}",
output.status,
String::from_utf8_lossy(&output.stderr)
);
let recorded = fs::read_to_string(&argv_dump).expect("fake compiler did not record argv");
let args: Vec<&str> = recorded.lines().collect();
let sep = args.iter().position(|a| *a == "--");
let map = args
.iter()
.position(|a| a.starts_with("-ffile-prefix-map="));
assert!(
map.is_some(),
"kache should have injected a -ffile-prefix-map flag; recorded argv: {args:?}"
);
assert!(
sep.is_some(),
"the `--` separator should be preserved in the spawned argv: {args:?}"
);
assert!(
map < sep,
"injected -ffile-prefix-map (idx {map:?}) must precede `--` (idx {sep:?}), \
else the driver treats it as an input file (#300); recorded argv: {args:?}"
);
}