From 85b6ccd04b841ecc3b4e35492bf7aae8766fed56 Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Thu, 20 Aug 2026 18:02:49 -0400 Subject: [PATCH] docs(web-testing): build with -j 2 and remove a worktree when it lands The worktree section carried a machine-load workaround that traded correctness for a warm build, and the dev scripts implemented it. Both now use the target/ of whichever worktree they run in. --- CLAUDE.md | 3 --- scripts/dev-instance.sh | 6 ++++-- scripts/dev-session.sh | 5 +++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2b0ab06..763a9a5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,9 +72,6 @@ After a feature is merged: A fresh worktree has no `target/` and no `web/node_modules`, so the first build in it compiles the whole dependency tree — `atrium-*`, the AWS SDK, `tokio` — before it can run a single test. That is minutes of CPU per worktree, and several agents doing it at once is what puts this machine under load. -- Point cargo at one shared directory: `export CARGO_TARGET_DIR="$HOME/.cache/lance-blue-target"`. The second worktree onwards then reuses the first one's artifacts. This cannot go in a committed `.cargo/config.toml`: a relative `build.target-dir` resolves inside each worktree, which is the thing being avoided. -- Cargo takes a file lock on the target directory, so two builds sharing one serialise rather than running together — you will see `Blocking waiting for file lock on build directory`. That is the intended trade: waiting for a warm build beats two cold ones competing for the same cores. -- Sharing it costs one thing, and it is quiet: two worktrees have identical manifests, so cargo gives them the same unit hash and tells them apart on mtimes alone. `git worktree add` writes files with fresh mtimes but a `cargo test` run right after one in another worktree can still be answered from that worktree's binary — it prints `Finished`, runs, and passes, having tested code you did not write. Check for a `Compiling headquarters-api` line naming *your* path; `find services -name '*.rs' -exec touch {} +` forces one. - Always `-j 2`. A full-parallel build has taken this machine down. - `web/node_modules` can be symlinked from another worktree when `web/package-lock.json` is byte-identical between them. Check that first — if the lockfiles differ, install rather than link. - A worktree keeps its `target/` after the branch merges, and these run to gigabytes. Remove the worktree when the branch lands, not just the branch. diff --git a/scripts/dev-instance.sh b/scripts/dev-instance.sh index b5db2f7..5100727 100755 --- a/scripts/dev-instance.sh +++ b/scripts/dev-instance.sh @@ -66,6 +66,9 @@ cd "$(dirname "$0")/.." default_state_root="${TMPDIR:-/tmp}" dev_secret="0123456789abcdef0123456789abcdef" +# Where cargo puts the binary, in whichever worktree this is run from. +target_dir="$(git rev-parse --show-toplevel)/target" + wait_for_log_line() { # Polls $1 (a log file) for the first line matching extended regex $2, # printing the matched line once found. Bails if $3 (a pid) stops @@ -93,7 +96,7 @@ start_api() { local secret="${SESSION_SECRET:-$dev_secret}" DB_PATH="$db" SESSION_SECRET="$secret" WEB_ORIGIN="$web_origin" BIND_ADDR=127.0.0.1:0 \ - "$CARGO_TARGET_DIR/debug/headquarters-api" \ + "$target_dir/debug/headquarters-api" \ >"$state_dir/api.log" 2>&1 & local api_pid=$! @@ -143,7 +146,6 @@ cmd_start() { state_dir="${state_dir:-$(mktemp -d "$default_state_root/headquarters-dev.XXXXXX")}" mkdir -p "$state_dir" - export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$HOME/.cache/lance-blue-target}" cargo build -p headquarters-api -j 2 local api_port="" web_port="" diff --git a/scripts/dev-session.sh b/scripts/dev-session.sh index e347c67..694c489 100755 --- a/scripts/dev-session.sh +++ b/scripts/dev-session.sh @@ -29,11 +29,12 @@ handle="${3:-}" exit 1 } -export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$HOME/.cache/lance-blue-target}" +# Where cargo puts the binary, in whichever worktree this is run from. +target_dir="$(git rev-parse --show-toplevel)/target" export DEV_SESSION_DB="$state_dir/db.sqlite" export SESSION_SECRET="${SESSION_SECRET:-0123456789abcdef0123456789abcdef}" [ -n "$did" ] && export DEV_SESSION_DID="$did" [ -n "$handle" ] && export DEV_SESSION_HANDLE="$handle" cargo build -p headquarters-api --bin dev_session -j 2 >&2 -"$CARGO_TARGET_DIR/debug/dev_session" +"$target_dir/debug/dev_session" -- 2.51.2