Release v0.75.0 - #3924
Conversation
worktrunk-bot
left a comment
There was a problem hiding this comment.
Reviewed the release mechanics (version bump, changelog coverage against the 47 PRs merged since v0.74.0) and the two code commits the branch carries. The changelog reads accurate — I spot-checked the Git 2.43 entry against command_requires_supported_git in src/main.rs, which does exempt exactly wt config shell. Three things below.
The one I'd want resolved before merge is the rc-file append: swapping write_atomically for write_all on the user's ~/.zshrc trades a whole-file race for a torn-line risk, and there's no rollback. write_all returns Err after having written some bytes when the underlying write short-writes and then fails — ENOSPC or a quota hit during wt config shell install leaves ~/.zshrc ending in a half-written if command -v wt >/dev/null 2>&1; then eval "$(comm, an unterminated quote that breaks every new shell. Under write_atomically the same failure left the file untouched. We hold the exclusive lock and know the pre-write length, so the truncate-back is cheap; inline suggestion on the write.
Separately, the new CLAUDE.md clause is stronger than the code. "never truncate or rebuild such a file" is contradicted by uninstall_previewed_lines in the very file this diff edits — it reads the rc file, filters lines, and hands the whole rebuilt string to write_atomically (the function whose own spec in src/utils.rs still opens "Every file that reaches this function is one a torn write breaks — rc files and shell wrappers the user's shell sources at startup"). So the two docs now disagree about whether rc files are a write_atomically client. Worth noting too that the lock closes only the install half of the read-modify-write: uninstall takes no lock, so wt config shell uninstall racing an install still drops the appended line. The changelog's "overlapping installs lock and reread rc files" is precise about this; CLAUDE.md's absolute is not.
Angles that came back clean
src/git/repository/diff.rs—as_chunks::<2>().0.iter()is behaviour-identical tochunks_exact(2): the remainder is discarded either way andpair[0]/pair[1]index a[String; 2]the same as a 2-element slice. MSRV is fine —lintruns pre-commit's clippy on the pinned 1.97 toolchain and passed.- Hard-link and inode preservation is a genuine improvement over the rename, and
test_configure_shell_appends_without_replacing_existing_filepins it. - Symlinked rc files (chezmoi/stow) still work: append mode writes through the link, same net effect as
write_atomically's canonicalize step. - No duplication —
contains_shell_integrationis an extraction from the inline loop, andacquire_config_lockinsrc/config/user/mutation.rslocks a sidecar.lock, so it isn't reusable for an rc file. - Bundling code fixes into the release commit matches the v0.72.0 and v0.74.0 release PRs, so not flagging it.
One small gap: test_configure_shell_rereads_open_file_before_appending calls append_shell_integration_if_missing directly, so nothing exercises configure_shell_file's open → lock → recheck wiring end to end. A refactor that dropped the lock_exclusive() call would keep both new tests green.
Not approving — the partial-write path is a new way for wt to leave a user's shell startup broken, which is the failure class the Data Safety section in CLAUDE.md exists for, and it's your call whether the rollback is worth the four lines.
|
pre-commit.ci run
|
worktrunk-bot
left a comment
There was a problem hiding this comment.
89d248c2e clears all three earlier threads: the append path reports a short write instead of truncating, CLAUDE.md now scopes the append rule to install and points at uninstall_previewed_lines for the rewrite direction, and the changelog entry links both PRs. Declining to retry the remainder of a short write is the right call for an O_APPEND handle — retrying would let a non-wt appender interleave between the two writes and split the line, which the exclusive lock can't prevent.
One new problem, in the added test_configure_shell_opens_rc_with_exclusive_lock: the WouldBlock assertion is Unix-only and will fail test (windows).
try_lock_exclusive here is fs2::FileExt's — std has try_lock/try_lock_shared but no try_lock_exclusive, so no inherent method shadows the trait. On Unix fs2 maps contention to EWOULDBLOCK, which decodes to ErrorKind::WouldBlock. On Windows its lock_file returns Error::last_os_error() after a failed LockFileEx(… | LOCKFILE_FAIL_IMMEDIATELY), i.e. ERROR_LOCK_VIOLATION (33), and std's Windows decode_error_kind has no arm for that value — it falls through to Uncategorized. (WSAEWOULDBLOCK is 10035, a separate arm in the second match.) fs2's own test suite compares raw_os_error() against lock_contended_error() rather than comparing kinds, for exactly this reason, and this repo already does the portable thing: fixture_lock_excludes_an_independent_handle in tests/helpers/wt-perf/src/lib.rs asserts only try_lock_exclusive().is_err(). test (macos) passing on this head is consistent with the Unix half of that.
The inline suggestion swaps the kind comparison for fs2::lock_contended_error().raw_os_error(), which keeps the assertion able to tell contention apart from an unrelated open/lock error. Bare .is_err() matching the wt-perf test is fine too.
Not approving while a test the commit adds is red on one platform.
Summary
Release Worktrunk 0.75.0. The user-facing release adds the unified picker diff and raises the minimum Git version to 2.43, while correcting list collection gates and conflict checks, timed child cleanup, long Windows paths, shell configuration concurrency, diagnostic profiling, and fenced HTML handling.
The release also updates agent and worktree guidance, the
wt uprecipe, the docs site, and library API notes. Release preparation found and fixed a concurrent rc-file overwrite in the shell installation path before tagging. The final implementation locks and rereads the open rc file, offers the addition in one write attempt, and reports a proven short write without truncating user or concurrent data.Validation
cargo run -- hook pre-merge --yes— 4,707 tests passed, 1 skipped; Clippy, formatting, lockfile, docs, doctests, snapshots, and repository policy hooks passedtask coverage— 4,707 tests passed with shell-integration coverage enabled; every deterministic new path is covered, leaving only the OS lock-error backstop uncovered7f5d245983317bcd5c3d798739b4d8f4f3fe7d0acargo-semver-checks0.50.0 — confirmed breaking public library API changes, requiring the pre-1.0 minor bumpcargo checkcargo test --bin wt md_help— 27 passed after merging the latest test-only drift from the default branch