mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
codex/remove-codex-cloud-specific-tests
12 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
897f7d7193 |
fix(tests): extend the spawn pin to benches; correct the pin's cost note (#3792)
Follow-up to #3784, prompted by a history audit of the spawn-flake family. Benches still spawned `env!("CARGO_BIN_EXE_wt")` — the uplifted path the suite stopped spawning — so a concurrent build could fail a bench run's spawns; all 11 sites now route through `wt_bin()` and `test_wt_spawns_are_pinned` scans `benches/` too, making the rule exceptionless. The pin's docstring also claimed the hardlink shares the `deps/` artifact's inode: true where cargo uplifts by hardlink (Linux), but macOS uplifts by copy-on-write clone — the pin keeps the clone, whose blocks stay shared with `deps/` (measured: cloning the 70 MB binary consumes 8 KB), so the no-cost conclusion stands with the mechanism now stated per platform, plus why nothing sweeps the directory. > _This was written by Claude Code on behalf of max-sixty_ --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
00ab0ffa26 |
Canonicalize benchmark fixtures and variants (#3761)
Benchmark fixtures still encoded the benchmark that first needed each repository state, which left overlapping recipes and variants after the earlier harness consolidation. This change reduces the fixture catalog to two provenance-based bases: `Generated` builds an ordinary Git repository locally, while `Imported` copies the pinned `rust-lang/rust` corpus. Worktree, branch, and remote-ref populations remain parameters on `Generated`; prune candidates and backdrop are overlays that work with either base. The generated base deliberately combines heterogeneous worktree states, history-spread branches, and optional remote refs so ordinary list, completion, picker, first-output, alias, remove, and prune benchmarks can share it. Imported history-spread branches and clean base-tip worktrees carry their own commits, preserving the base populations without making them incidental prune candidates when overlays advance the default branch. The benchmark matrix now keeps single-factor contrasts: list scaling uses the 1- and 8-worktree endpoints; alias dispatch has a startup floor, two population endpoints, and one warm/cold variable-resolution pair; completion keeps one full-surface case; remove and prune vary cache or hook state only where the command exercises it. Historical recipes, redundant cache rows, and intermediate scaling points are removed. Manual setup paths live under `target/`, and the benchmark guide documents the resulting fixture and cache model. Tests: `cargo run -- hook pre-merge --yes` after merging current `main` (4,571 tests); targeted Criterion test-mode runs; `cargo test -p wt-perf`; benchmark check, clippy, formatting, and diff checks. > _This was written by Codex on behalf of max-sixty_ |
||
|
|
970976bd32 |
Consolidate benchmark recipes and cases (#3721)
Benchmark fixtures had accumulated around individual call sites, leaving the same repository shapes and command modes expressed several ways. This change makes repository state the organizing concept: benchmark groups select semantic `FixtureRecipe`s, share table-driven cases, and retain separate fixtures only when a controlled contrast, destructive precondition, or disproportionate setup cost requires one. The real-repository list benchmarks now share one pinned `rust-lang/rust` fixture with eight worktrees and fifty branches spread across history. The list matrix keeps default, branch, warm, and cold coverage without maintaining several “real” repository handles. Remove and prune cases share the same case machinery, while the destructive large-repository prune state remains separate. The scheduled workflow now converts Criterion estimates directly with `jq`, removing the one-off Python converter and its tests. The benchmark guide records the canonical-fixture principle and the remaining recipe-to-group mapping. Tests: `cargo run -- hook pre-merge --yes` (4,551 tests); `cargo bench --bench list large_repository -- --test`; `cargo test -p wt-perf`; benchmark check, clippy, formatting, and diff checks. > _This was written by Codex on behalf of max-sixty_. |
||
|
|
7fe28bf574 |
Consolidate benchmark fixtures and harness (#3669)
Benchmark targets had each reimplemented temporary-repository ownership, linked-worktree paths, subprocess isolation, and warm/cold loops. This adds a shared `FixtureRepo` and canonical command/cache helpers while leaving each scenario-specific workload and destructive lifecycle explicit. All 41 existing Criterion IDs, fixture dimensions, command arguments, and cache ordering are preserved. The completion benchmark now also fails when its measured subprocess fails instead of silently accepting the result. Tests: `cargo run -- hook pre-merge --yes`; `cargo test -p wt-perf`; `cargo check --benches -p worktrunk -p wt-perf`; representative Criterion test-mode runs for completion, list, first-output, remove, and prune. > _This was written by Claude Code on behalf of max_. |
||
|
|
18d2bef84b |
refactor(perf): canonicalize the benchmark / wt-perf system (#3403)
Implements the design proposal from this branch's first commit
(
|
||
|
|
d7c8428e16 |
bench: use BatchSize::PerIteration for cold-cache variants (#2728)
## Summary Cold benchmark variants in `list.rs`, `remove.rs`, and `time_to_first_output.rs` were passing `BatchSize::SmallInput` to `iter_batched`. Under `SmallInput`, criterion calls the setup closure once per batch up front and then runs the routines back-to-back inside a single timing window — so when setup is `invalidate_caches_auto`, only iter 1 per batch is actually cold and iters 2-N read from the cache the previous routine just populated. The reported "cold" medians were warm-biased averages. `BatchSize::PerIteration` switches to `setup → time(routine)` per iter, so every measured iter is genuinely cold. The setup is far cheaper than a `wt` subprocess, so per-iter `Instant::now` overhead doesn't dominate. Codex flagged this on the sibling `picker_preview` bench (#2721); that PR landed `PerIteration` for its cold path, and this aligns the rest of the bench suite. ## Measured corrections | Variant | Before median | After median | Spread (before → after) | Median Δ | |---|---|---|---|---| | `list full/cold/8` | 113.5 ms | 107.1 ms | 16.0 → 3.9 ms | −5.7% (n.s., p=0.14) | | `remove_e2e/first_output` | 48.2 ms | 86.4 ms | 2.6 → 17.9 ms | **+44.4%** (p<0.001) | | `first_output/remove` | 50.5 ms | 69.6 ms | 2.4 → 0.65 ms | **+23.0%** (p<0.001) | `remove_e2e/first_output` is the starkest correction — `compute_integration_lazy` writes `is-ancestor` / `has-added-changes` / `merge-add-probe` entries, so warm-bias was substantial. `first_output/remove` is the cleanest demonstration of variance tightening (3.7× tighter spread). `list full/cold/8` doesn't move the median significantly but the upper-tail outliers that warm-bias was inflating disappear. ## Scope Only the four `iter_batched(… invalidate_caches_auto, …, BatchSize::SmallInput)` call sites are switched: - `benches/list.rs` `run_benchmark` (covers `skeleton`, `full`, `worktree_scaling`, `many_branches`, `divergent_branches` cold variants) - `benches/list.rs` `bench_real_repo` cold path - `benches/remove.rs` `first_output` - `benches/time_to_first_output.rs` `remove` Other `BatchSize::SmallInput` sites in `remove.rs` (`no_hooks`, `with_hooks`) use `recreate_worktree` as setup — that doesn't invalidate a cache the routine repopulates, so they stay as-is. `benches/CLAUDE.md` "Cache Handling" gets a paragraph so future bench authors reach for `PerIteration` when the setup invalidates a cache the routine repopulates. ## Test plan - [x] `cargo run -- hook pre-merge --yes` — 3667 tests pass, 0 failed - [x] Each cold variant run before+after on this branch with `--save-baseline` / `--baseline` Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
c710147c8c |
fix(bench): unbreak wt-perf invalidate; consolidate env-isolation helpers (#2540)
## Summary Two bugs in `wt_perf::invalidate_caches_auto`, plus consolidation of the env-isolation helpers shared between tests and benches. ## Bugs fixed **(1) Silent unset under inherited `GIT_DIR`.** `invalidate_caches_auto` shelled to `git config --unset worktrunk.default-branch` via `worktrunk::shell_exec::Cmd`. `Cmd::apply_common_settings` re-injects normalized inherited `GIT_*` path vars resolved against the wt-perf process's startup cwd (issue #1914 — correct for `wt`-from-git-alias where parent and child target the same repo). For wt-perf, which operates on an explicit, possibly-unrelated repo path, the override redirected the unset to the wrong git dir; the resulting non-zero exit was swallowed by `let _ =`, and the cache stayed put. Reproducer: ```bash cd /tmp && GIT_DIR=.git target/release/wt-perf invalidate /tmp/wt-prof-test # previously: silently leaves worktrunk.default-branch in place # now: actually unsets it ``` **(2) Linked worktrees never cleared.** `invalidate_caches_auto` resolved `<repo_path>/.git` naively. When `repo_path` is a *linked* worktree, `.git` is a file (gitdir-pointer), not a directory, so every `fs::remove_*` call no-op'd silently — `.git/wt/cache/`, `.git/index`, `packed-refs`, commit-graph all survived. Existing bench callers all pass the main worktree, so no current bench was affected, but the function's contract was broken for linked-worktree inputs. ## Fixes - wt-perf no longer routes through `worktrunk::shell_exec::Cmd`. All `git` subprocess work uses `std::process::Command` directly via a small `git_command()` helper that delegates to `worktrunk::testing::configure_git_cmd`. The inherited-`GIT_*` normalization (which was the root of bug 1) doesn't apply to plain `Command`. - `invalidate_caches_auto` resolves the git common dir from the filesystem — reads `.git` as dir-or-pointer, strips `worktrees/<name>` for linked worktrees — so the cache root is correct regardless of which worktree of a repo is named. - The `let _ =` on the unset is gone; non-success/non-5 exits print a one-line `eprintln!` so a future regression can't hide the same way. ## Consolidation Touched four near-duplicate env-isolation helpers (`configure_cli_command`, `configure_git_cmd`, `configure_git_env`, `wt_perf::isolate_cmd`). The shared core is now in `worktrunk::testing`: - `pub fn isolate_subprocess_env(cmd, user_config: Option<&Path>)` — strips host context (`GIT_*`, `WORKTRUNK_*`, `NO_COLOR`, `SHELL`, `PSModulePath`) and sets baseline `WORKTRUNK_*_PATH`. Used by `configure_cli_command` (test-side, layers on test determinism) and every bench (no extra layer — benches want realism). - `pub fn scrub_git_path_vars(cmd)` — env_remove the five `GIT_*` repo-discovery vars. Called defensively from `configure_git_cmd`/`configure_git_env` so test code that spawns `git` outside a `wt`-parent isn't vulnerable to the same redirect. - `wt_perf::isolate_cmd` deleted. Five bench files now import `worktrunk::testing::isolate_subprocess_env` directly. - Path strings unified: `/nonexistent/wt/{config,approvals}.toml` and `/etc/xdg/worktrunk/config.toml` (preserved as the real XDG path). 47 snapshots regenerated. ## Test plan - [x] `cargo clippy --all-targets --workspace` clean - [x] 1072 + 607 lib unit tests pass - [x] 1589 integration tests pass (vs. baseline's 3 pre-existing failures, which the snapshot regen also resolved) - [x] All 5 benches compile (`cargo bench --no-run`) - [x] Bug 1 (GIT_DIR redirect): unset succeeds - [x] Bug 2 (linked worktree): cache and config both cleared from any worktree path - [x] Vanilla path: still works 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
83d6d076bb |
bench: invalidate wt caches per iteration in remove/TTFO benches (#2341)
## Summary `wt remove` populates `.git/wt/cache/` via `compute_integration_lazy` whenever `BranchDeletionMode` isn't force-delete (the CLI's `--force` is `force_worktree`, not `--force-delete`). The `remove_e2e/first_output` and `first_output/remove` benches used `b.iter` with no invalidation, so iter 1 was cold and iter 2+ hit the cache — reported timings reflected warm-cache cost, not the first-invocation TTFO users see. ## Changes - `benches/remove.rs::first_output` and `benches/time_to_first_output.rs::remove` switch to `iter_batched` + `invalidate_caches_auto`. - `wt_perf::invalidate_caches_auto` now also unsets `worktrunk.default-branch` (git config). That cache contributes ~17ms per iteration on a typical-8 repo (166ms with default-branch cached vs 183ms fully cold) — measurable but small enough that always clearing it is simpler than introducing a second mode. - `benches/CLAUDE.md` documents the rule, the full list of what `invalidate_caches_auto` clears (including what it deliberately preserves — `worktrunk.history`, `worktrunk.hints.*`, `worktrunk.state.*`, `.git/wt/logs/`, `.git/wt/trash/`), and which commands populate `.git/wt/cache/`. Audit found no other benches affected: `completion.rs` and `cow_copy.rs` don't touch the cache; `list.rs` already wires warm/cold via `BenchConfig`; `wt switch` and `wt list` under `WORKTRUNK_FIRST_OUTPUT=1` exit before the writers run; `remove.rs::no_hooks`/`with_hooks` short-circuit at `same_commit` because `recreate_worktree` rebuilds the branch at main's HEAD. > _This was written by Claude Code on behalf of Maximilian Roos_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
679fe539fe |
Deprecate --no-verify in favor of --no-hooks (#1932)
`--no-hooks` describes what the flag does — skip hooks. `--no-verify` was inherited from git's naming but doesn't match worktrunk's semantics (there's no "verification" step being skipped). `--no-verify` remains as a hidden alias that emits a deprecation warning, retained for at least one release cycle per the project's deprecation policy. Changes across switch, remove, merge, step commit, and step squash: - `--no-hooks` is the canonical visible flag - `--no-verify` hidden, emits `▲ --no-verify is deprecated; use --no-hooks instead` - Error hints (`↳ To skip pre-merge hooks, re-run with --no-hooks`), info messages, help text, docs, and config examples all updated - `resolve_verify()` helper in main.rs deduplicates the deprecation logic - Backward-compatibility test verifies `--no-verify` still works > _This was written by Claude Code on behalf of @max-sixty_ --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
afa0a478c9 |
refactor: isolate benchmark commands and consolidate shared utilities into wt-perf (#1878)
Add `isolate_cmd` and `run_git_ok` to the shared `wt-perf` crate and call `isolate_cmd` from all benchmark command sites. Previously only `benches/remove.rs` isolated commands from the host environment; the other benchmarks inherited host `GIT_*`, `WORKTRUNK_*`, `SHELL`, and `NO_COLOR` vars, making results non-reproducible across environments. `isolate_cmd` takes `Option<&Path>` for the user config — `None` uses a nonexistent path (defaults only), `Some(path)` uses a real config file (e.g., `remove.rs` with hooks). `run_git_ok` is the non-panicking variant of `run_git` for best-effort cleanup operations. > _This was written by Claude Code on behalf of @max-sixty_ Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
b1ab14c488 |
chore: remove run_git_ok helper from remove benchmark (#1871)
Inline the two cleanup calls using `Cmd::new("git")...run()` directly
instead of a dedicated `run_git_ok` wrapper — the same pattern used
throughout the codebase for fallible git commands.
Follow-up to #1858.
> _This was written by Claude Code on behalf of maximilian_
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
||
|
|
bd87f2a146 |
fix: background removal blocks for 1s due to shell parsing bug (#1858)
`spawn_detached_unix` constructed the shell command as `sh -c "sleep 1
&& rmdir ...; rm -rf ... &"`. In POSIX shell, `;` has lower precedence
than `&`, so this parses as two statements: `sleep 1 && rmdir ...` runs
**synchronously** (1 second block), then only `rm -rf ... &` is
backgrounded. Every `wt remove` paid a 1-second penalty.
The fix wraps compound commands in braces — `{ sleep 1 && rmdir ...; rm
-rf ...; } &` — so `&` backgrounds the entire group. This affects all
callers of `spawn_detached` (remove, prune, merge, hooks).
Tests that asserted `!path.exists()` after removal now use
`assert_worktree_removed()` which accepts an empty placeholder directory
(the placeholder is cleaned up by the now-correctly-backgrounded `sleep
1 && rmdir`). Also fixes a pre-existing race in
`test_standalone_hook_post_merge` / `post_create` where background hooks
were checked immediately instead of polled.
Also adds `benches/remove.rs` for measuring end-to-end remove
performance.
> _This was written by Claude Code on behalf of maximilian_
---------
Co-authored-by: Claude <noreply@anthropic.com>
|