diff --git a/host/src/builder/mod.rs b/host/src/builder/mod.rs index bf54efb..b1c17e2 100644 --- a/host/src/builder/mod.rs +++ b/host/src/builder/mod.rs @@ -123,12 +123,15 @@ impl Builder { b"Signature: 8a477f597d28d172789f06886806bc55\n", )?; std::fs::write(base.join("last-used"), [])?; - let cwd = source.join( - world_cwd - .strip_prefix(&workspace) - .expect("workspace is an ancestor of cwd") - .trim_start_matches('/'), - ); + let relative = world_cwd + .strip_prefix(&workspace) + .expect("workspace is an ancestor of cwd") + .trim_start_matches('/'); + let cwd = if relative.is_empty() { + source.clone() + } else { + source.join(relative) + }; let mut fetch = Command::new("cargo"); if action == "add" { fetch.args(&request.argv).arg("--dry-run"); @@ -274,7 +277,6 @@ 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=[{:?},{:?}]", @@ -282,6 +284,8 @@ impl Builder { tools.join("run.nu") )); } + // Keep all global config flags before the subcommand so Cargo retains them. + cmd.args(&args[..split]); if compiles { cmd.args([ "--target", diff --git a/host/src/process/http.rs b/host/src/process/http.rs index 747f5ae..8772a84 100644 --- a/host/src/process/http.rs +++ b/host/src/process/http.rs @@ -49,7 +49,7 @@ impl WasiHttpHooks for Hooks { if request.method() == http::Method::POST && request.uri().path() == "/cargo" { return Ok(( crate::api::stream(&router, request), - Box::new(async { Ok(()) }), + Box::new(async { Ok(()) }) as Io, )); } return Ok(response(crate::api::handle(&router, caller, request).await)); diff --git a/host/tests/builder.rs b/host/tests/builder.rs index ef46819..019823a 100644 --- a/host/tests/builder.rs +++ b/host/tests/builder.rs @@ -171,7 +171,8 @@ async fn cargo_build_test_and_source_changes() -> anyhow::Result<()> { .await?; assert_eq!(code, 0, "{out}"); assert!(out.contains("INTEGRATION_CASE"), "{out}"); - let (code, out) = cargo(&runtime, &["test", "fail"]).await?; + // WASI aborts on panic, so disable capture to expose the panic message. + let (code, out) = cargo(&runtime, &["test", "fail", "--", "--nocapture"]).await?; assert_eq!(code, 101, "{out}"); assert!(out.contains("intentional fixture failure"), "{out}"); let (code, out) = cargo(&runtime, &["test", "--no-run"]).await?; @@ -291,7 +292,7 @@ async fn timeout_and_cancellation() -> anyhow::Result<()> { std::fs::create_dir_all(&bin)?; std::fs::copy(binaries.join("cargo.wasm"), bin.join("cargo.wasm"))?; let runtime = Runtime::new(world)?; - let code = runtime + let error = runtime .exec( Command::Argv(vec!["/bin/cargo.wasm".into(), "build".into()]), Options { @@ -301,10 +302,11 @@ async fn timeout_and_cancellation() -> anyhow::Result<()> { }, &mut |_, _| {}, ) - .await?; - assert_ne!(code, 0); + .await + .unwrap_err(); + assert!(error.to_string().contains("timed out"), "{error}"); let (code, out) = - tokio::time::timeout(Duration::from_secs(5), cargo(&runtime, &["metadata"])).await??; + tokio::time::timeout(Duration::from_secs(20), cargo(&runtime, &["metadata"])).await??; assert_eq!( code, 0, "the canceled build still held the builder lock: {out}"