builder: delegate run selection and preserve test working directories

This commit is contained in:
2026-11-07 13:24:53 +00:00
parent 0be19f3f9c
commit e53211eff1
6 changed files with 137 additions and 27 deletions
+55 -15
View File
@@ -24,12 +24,24 @@ pub struct Request {
pub cwd: String,
pub timeout_secs: Option<u64>,
}
#[derive(Serialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct Executable {
pub path: String,
pub cwd: String,
}
#[derive(Serialize)]
#[serde(tag = "event", rename_all = "snake_case")]
pub enum Event {
Stdout { bytes: Vec<u8> },
Stderr { bytes: Vec<u8> },
Exit { code: i32, executables: Vec<String> },
Stdout {
bytes: Vec<u8>,
},
Stderr {
bytes: Vec<u8>,
},
Exit {
code: i32,
executables: Vec<Executable>,
},
}
pub struct Builder {
root: Arc<dyn Layer>,
@@ -150,6 +162,7 @@ impl Builder {
"link.nu",
include_bytes!("../../../userland/cwd-init/link.nu").as_slice(),
),
("run.nu", include_bytes!("run.nu").as_slice()),
] {
std::fs::write(tools.join(name), bytes)?;
}
@@ -178,6 +191,10 @@ impl Builder {
return Ok(());
}
let kache = executable("kache")?;
let run_path = target_mount.join("run-path");
if action == "run" && run_path.exists() {
std::fs::remove_file(&run_path)?;
}
let mut cmd = Command::new("bwrap");
cmd.args([
"--unshare-user",
@@ -220,6 +237,8 @@ impl Builder {
.arg(&cache)
.args(["--setenv", "SAUSAGE_CWD_INIT"])
.arg(tools.join("init.o"))
.args(["--setenv", "SAUSAGE_RUN_PATH"])
.arg(&run_path)
.args(["--setenv", "CARGO_BUILD_JOBS", "2"]);
for name in [
"CC_wasm32_wasip2",
@@ -242,9 +261,6 @@ impl Builder {
"target.wasm32-wasip2.rustflags=['-C','link-arg=sausage-cwd-init']",
]);
let mut args = request.argv.clone();
if action == "run" {
args[0] = "build".into();
}
if matches!(action, "run" | "test")
&& let Some(index) = args.iter().position(|a| a == "--")
{
@@ -259,6 +275,13 @@ impl Builder {
}
let split = args.iter().position(|a| a == "--").unwrap_or(args.len());
cmd.args(&args[..split]);
if action == "run" {
cmd.arg("--config").arg(format!(
"target.wasm32-wasip2.runner=[{:?},{:?}]",
executable("nu")?,
tools.join("run.nu")
));
}
if compiles {
cmd.args([
"--target",
@@ -282,23 +305,40 @@ impl Builder {
)
.await?;
}
if code == 0 && action == "run" && run_path.exists() {
let path = std::fs::read_to_string(&run_path)?;
let relative = Path::new(&path).strip_prefix(&target)?;
executables.push(Executable {
path: format!("{world_target}/{}", relative.display()),
cwd: world_cwd.clone(),
});
}
if code == 0
&& matches!(action, "test" | "run")
&& !(action == "test"
&& request
.argv
.iter()
.take_while(|a| a.as_str() != "--")
.any(|a| a == "--no-run"))
&& action == "test"
&& !request
.argv
.iter()
.take_while(|a| a.as_str() != "--")
.any(|a| a == "--no-run")
{
for line in stdout.split(|b| *b == b'\n') {
if let Ok(value) = serde_json::from_slice::<serde_json::Value>(line)
&& value["reason"] == "compiler-artifact"
&& (action == "run" || value["profile"]["test"] == true)
&& value["profile"]["test"] == true
&& let Some(path) = value["executable"].as_str()
&& let Ok(relative) = Path::new(path).strip_prefix(&target)
{
executables.push(format!("{world_target}/{}", relative.display()));
let manifest = Path::new(
value["manifest_path"]
.as_str()
.context("missing test manifest")?,
);
let package = manifest.parent().unwrap().strip_prefix(&source)?;
let cwd = sausage_vfs::resolve(&workspace, &package.to_string_lossy());
executables.push(Executable {
path: format!("{world_target}/{}", relative.display()),
cwd,
});
}
}
executables.sort();