fix(brew): relocate shebang executables with long prefixes - #11632
Conversation
📝 WalkthroughWalkthroughBrew relocation now detects valid shebang executables, including binary-containing zipapps. It applies length-changing path replacements while retaining existing Mach-O and Linux ELF handling. ChangesShebang relocation
Estimated code review effort: 2 (Simple) | ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryThe PR fixes relocation of NUL-backed shebang executables by replacing placeholders only in their shebang preamble while preserving the binary payload.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; both previously reported relocation issues are addressed by line-bounded shebang validation and payload-preserving replacement. Important Files Changed
Reviews (2): Last reviewed commit: "fix(brew): relocate shebang executables ..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/system/packages/brew/relocate.rs`:
- Around line 89-97: Update is_text_executable to inspect only the first shebang
line, stopping at \n or \r, and require a non-empty interpreter with no NUL
bytes. Preserve the existing prefix limit and ensure relocate_keg does not
classify binary payloads such as "#!\n\0payload" as text; add a regression
covering that input.
- Around line 206-212: Restrict relocation replacements for ZIP apps to the
prepended shebang, or rebuild the ZIP while updating entry data, CRCs, sizes,
filename and extra-field lengths, and central-directory offsets. Update the
relevant relocation logic near the macho/ELF branch and extend its test with a
stored entry containing a placeholder, confirming the resulting archive remains
readable; verify any Brew guarantee that placeholders only occur in the shebang
before relying on it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: f8a11702-cd0a-418e-a19b-0e32cc528f96
📒 Files selected for processing (2)
docs/bootstrap/packages/brew.mdsrc/system/packages/brew/relocate.rs
Summary
Fix Linux Homebrew bottle relocation for shebang executables that contain binary data, such as Watchman's
watchman-diagPython zipapp.On Linux,
brew:watchmanfailed while pouring the bottle with:Root cause
watchman-diagstarts with a Python shebang but contains a ZIP payload and NUL bytes. mise therefore classified it as an ordinary fixed-width binary. The Linuxbrew prefix is longer than the placeholder slot, so relocation failed.Homebrew treats shebang executables as text executables before checking for binary contents and performs variable-length replacement. Inspection of the original Linux arm64 Watchman bottle confirmed that the Homebrew prefix placeholder occurs only in the shebang. Extending that shebang preserves both ZIP integrity and executable behavior.
Changes
Validation
mise exec -- cargo test --all-features system::packages::brew::relocate::testsmise exec -- cargo check --all-featuresmise exec -- cargo clippy --workspace --all-features --all-targets -- -D warningsmise exec -- cargo fmt --all -- --checkdocs/bootstrap/packages/brew.mdbrew:watchmanapply and final status succeededwatchman --versionreturned2026.07.27.00watchman-diagretained a valid ZIP payload/home/linuxbrew/.linuxbrew/opt/python@3.14/bin/python3.14MISE_SYSTEM_BREW_PREFIX=/tmp/hb-macos:brew:fswatchandbrew:watchmanboth installed successfully2026.07.27.00watchman-diagremained a valid ZIP archive with the relocated test prefixmise run formatandmise run lintcould not start because hk requires a Git working copy while this checkout is managed by Sapling. The applicable Rust, documentation, check, and Clippy commands above passed individually.Addresses #5655
AI-assisted — Tool: Codex; model: OpenAI/GPT-5; version: unavailable.
Summary by CodeRabbit
Bug Fixes
Tests