claw-cargo: map cargo profile name to actual target dir
Cargo aliases the `dev`/`test` profiles to `target/debug/` and
`release`/`bench` to `target/release/`. claw-cargo was using the
profile name verbatim as the subdirectory, so with the default
`profile = "dev"` config it looked for `target/dev/` — a directory
that never exists — and silently skipped the capture+upload step
after a successful cold build.
Symptom in the field (pilot deploy on tank, 2026-07-12):
Finished `dev` profile [unoptimized + debuginfo] target(s) in 12.22s
cargo build finished in 12.2461178s
target dir ./target/dev does not exist after cargo build — skipping upload
Fix: `target_subdir_for(profile)` maps aliases to their real dirs;
custom profile names pass through unchanged. Applied in `cmd_build`
and `cmd_prefetch`. Cheap unit test guards the mapping so the same
bug can't come back.
This commit is contained in:
@@ -365,7 +365,7 @@ async fn cmd_status(args: PeerArgs) -> Result<()> {
|
||||
|
||||
async fn cmd_prefetch(args: PrefetchArgs) -> Result<()> {
|
||||
let (workspace, resolved, fp) = setup_peer(&args.peer)?;
|
||||
let target_dir = workspace.join("target").join(&resolved.profile);
|
||||
let target_dir = workspace.join("target").join(target_subdir_for(&resolved.profile));
|
||||
|
||||
let (client, conn) = connect_peer(&resolved).await?;
|
||||
|
||||
@@ -485,7 +485,7 @@ async fn resolve_pin(
|
||||
|
||||
async fn cmd_build(args: BuildArgs) -> Result<()> {
|
||||
let (workspace, resolved, fp) = setup_peer(&args.peer)?;
|
||||
let target_dir = workspace.join("target").join(&resolved.profile);
|
||||
let target_dir = workspace.join("target").join(target_subdir_for(&resolved.profile));
|
||||
tracing::info!("fingerprint {}", fp);
|
||||
|
||||
let (client, conn) = connect_peer(&resolved).await?;
|
||||
@@ -911,6 +911,18 @@ async fn cmd_prewarm(args: PrewarmArgs) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Map a cargo profile name to the directory under `target/` cargo
|
||||
/// actually writes to. Cargo aliases `dev`/`test` to `debug/` and
|
||||
/// `release`/`bench` to `release/`; every other (custom) profile
|
||||
/// gets a directory of the same name.
|
||||
fn target_subdir_for(profile: &str) -> &str {
|
||||
match profile {
|
||||
"dev" | "test" => "debug",
|
||||
"release" | "bench" => "release",
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn run_cargo(
|
||||
workspace: &Path,
|
||||
profile: &str,
|
||||
@@ -928,3 +940,24 @@ fn run_cargo(
|
||||
let status = cmd.status().context("spawning cargo build")?;
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn target_subdir_matches_cargo_layout() {
|
||||
// Cargo's built-in profile aliases: dev + test both compile
|
||||
// into `target/debug/`; release + bench compile into
|
||||
// `target/release/`. Custom profiles get a dir of the same
|
||||
// name. Getting this wrong silently skips the capture step
|
||||
// ("target dir does not exist after cargo build") — the exact
|
||||
// failure mode we hit in the field on the first pilot run.
|
||||
assert_eq!(target_subdir_for("dev"), "debug");
|
||||
assert_eq!(target_subdir_for("test"), "debug");
|
||||
assert_eq!(target_subdir_for("release"), "release");
|
||||
assert_eq!(target_subdir_for("bench"), "release");
|
||||
assert_eq!(target_subdir_for("prod"), "prod");
|
||||
assert_eq!(target_subdir_for("hot-loop"), "hot-loop");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user