Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash caused by RubyGems require gem activation logic running before Bundler can properly register its own monkeypatches #7647

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -589,10 +589,13 @@ end

desc "Check RubyGems integration"
task :check_rubygems_integration do
# Bundler monkeypatches RubyGems in some ways that could potentially break gem
# activation. Run a non trivial binstub activation, with two different
# versions of a dependent gem installed.
# Bundler monkeypatches RubyGems in some ways that could potentially break gem activation.

# Run a non trivial binstub activation, with two different versions of a dependent gem installed.
sh("ruby -Ilib -S gem install reline:0.3.0 reline:0.3.1 irb && ruby -Ibundler/lib -rbundler -S irb --version")

# With two psych versions installed, load a gem that depends on pysch and then load rubygems extensions.
sh("ruby -Ilib -S gem install psych:5.1.1 psych:5.1.2 rdoc && ruby -Ibundler/lib -rrdoc/task -rbundler/rubygems_ext -e1")
end

namespace :man do
Expand Down
2 changes: 2 additions & 0 deletions bundler/lib/bundler/constants.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "rbconfig"

module Bundler
WINDOWS = RbConfig::CONFIG["host_os"] =~ /(msdos|mswin|djgpp|mingw)/
FREEBSD = RbConfig::CONFIG["host_os"].to_s.include?("bsd")
Expand Down
17 changes: 11 additions & 6 deletions bundler/lib/bundler/rubygems_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

require "rubygems" unless defined?(Gem)

require "rubygems/specification"

# We can't let `Gem::Source` be autoloaded in the `Gem::Specification#source`
# redefinition below, so we need to load it upfront. The reason is that if
# Bundler monkeypatches are loaded before RubyGems activates an executable (for
Expand All @@ -17,10 +15,6 @@
# `Gem::Source` from the redefined `Gem::Specification#source`.
require "rubygems/source"

require_relative "match_metadata"
require_relative "force_platform"
require_relative "match_platform"

# Cherry-pick fixes to `Gem.ruby_version` to be useful for modern Bundler
# versions and ignore patchlevels
# (https://github.com/rubygems/rubygems/pull/5472,
Expand All @@ -31,7 +25,12 @@
end

module Gem
require "rubygems/specification"

class Specification
require_relative "match_metadata"
require_relative "match_platform"

include ::Bundler::MatchMetadata
include ::Bundler::MatchPlatform

Expand Down Expand Up @@ -148,17 +147,23 @@ def dependencies_to_gemfile(dependencies, group = nil)

module BetterPermissionError
def data
require_relative "shared_helpers"

Bundler::SharedHelpers.filesystem_access(loaded_from, :read) do
super
end
end
end

require "rubygems/stub_specification"

class StubSpecification
prepend BetterPermissionError
end

class Dependency
require_relative "force_platform"

include ::Bundler::ForcePlatform

attr_accessor :source, :groups
Expand Down
6 changes: 2 additions & 4 deletions bundler/lib/bundler/rubygems_integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

module Bundler
class RubygemsIntegration
require "monitor"

EXT_LOCK = Monitor.new
autoload :Monitor, "monitor"

def initialize
@replaced_methods = {}
Expand Down Expand Up @@ -173,7 +171,7 @@ def ui=(obj)
end

def ext_lock
EXT_LOCK
@ext_lock ||= Monitor.new
end

def spec_from_gem(path)
Expand Down
10 changes: 6 additions & 4 deletions bundler/lib/bundler/shared_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# frozen_string_literal: true

require "pathname"
require "rbconfig"

require_relative "version"
require_relative "constants"
require_relative "rubygems_integration"
require_relative "current_ruby"

module Bundler
autoload :WINDOWS, File.expand_path("constants", __dir__)
autoload :FREEBSD, File.expand_path("constants", __dir__)
autoload :NULL, File.expand_path("constants", __dir__)

module SharedHelpers
autoload :Pathname, "pathname"

def root
gemfile = find_gemfile
raise GemfileNotFound, "Could not locate Gemfile" unless gemfile
Expand Down