Fix bundle binstub broken by gem update --system on Homebrew ruby#9688
Open
hsbt wants to merge 3 commits into
Open
Fix bundle binstub broken by gem update --system on Homebrew ruby#9688hsbt wants to merge 3 commits into
bundle binstub broken by gem update --system on Homebrew ruby#9688hsbt wants to merge 3 commits into
Conversation
`gem update --system` wrote the new default bundler gemspec next to the previous one, but extracted its executables under `Gem.default_dir`. On rubies where `Gem.default_specifications_dir` lives under a different root than `Gem.default_dir`, like Homebrew ruby, activating the default bundler then computes an executable path that does not exist, breaking the `bundle` binstub. Extract the executables and remove the previous default gem under the same root as the gemspec instead. #9685 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The default gemspec is already written to the default specifications directory before building the gem, so `installer.write_default_spec` just wrote the same file a second time. Drop the redundant call and let the installer only extract and generate the executables.
When a regular gem of the vendored bundler version was already installed, its files were removed from the default gemspec's gems directory instead of from default_dir. On rubies where those roots differ, like Homebrew ruby, the regular gem files were left behind after being promoted to the default gem. Remove them from default_dir, where regular gems actually live.
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes a RubyGems setup/gem update --system edge case where default Bundler gemspecs and extracted executables can end up under different roots (notably on Homebrew Ruby), causing bundle binstubs to fail with LoadError when activation resolves a non-existent executable path.
Changes:
- Install Bundler executables under the same root as the default Bundler gemspec (derived from
specs_dir) soGem.activate_and_load_bin_pathresolves a real path. - Correct removal of a promoted same-version regular Bundler gem to target
default_dir(where regular gems live), not the default gemspec root. - Add a regression test simulating the Homebrew-style split-root layout and asserting both cleanup and executable placement.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| lib/rubygems/commands/setup_command.rb | Align Bundler executable extraction directory with the default gemspec root; fix cleanup paths for prior default and promoted regular Bundler installs. |
| test/rubygems/test_gem_commands_setup_command.rb | Adds coverage for split-root default gemspec vs default gem install layouts to prevent bundle binstub regressions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On rubies where
Gem.default_specifications_dirlives under a different root thanGem.default_dir, like Homebrew ruby,gem update --systemwrote the new default bundler gemspec next to the previous one but extracted its executables underGem.default_dir. Activating the default bundler then resolved an executable path that never existed, so thebundlebinstub broke with aLoadErrorright after every RubyGems update until the user rangem install bundler. This installs the executables and removes the previous default gem under the same root as the gemspec so the two stay together.While fixing this I dropped a redundant second write of the default gemspec through the installer, and pointed the removal of a promoted same-version regular bundler gem at
default_dirwhere regular gems actually live instead of at the default gemspec root.Fixed #9685