summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2017-05-09 03:42:07 +0000
committerThe Bundler Bot <bot@bundler.io>2017-05-09 03:42:07 +0000
commita1925cb18c58232ba009df01478b65dfe43d51ba (patch)
tree829cd0a2acc72c4a00b8b2475db8cdf617df5a20
parent47e7dd0e93a11b40fa982aaef5eb7d35cb7c2717 (diff)
parentaeec3437f20c70624d778a7c40e0525dd69d3933 (diff)
downloadbundler-a1925cb18c58232ba009df01478b65dfe43d51ba.tar.gz
Auto merge of #5637 - bundler:seg-gem-finish-resolve, r=indirect
[RubygemsIntegration] Stub out Gem.finish_resolve Fixes https://github.com/rubygems/rubygems/issues/1911 Small novel: In RubyGems 2.6.11, I changed `Gem.finish_resolve` to respect all of the currently resolved (i.e. `Gem.loaded_specs`) gems. This fixed some bugs that would lead `Gem.finish_resolve` to incorrectly raise gem incompatibility exceptions. That's great, except Bundler's resolver doesn't always resolve the same thing as RG's. In particular, `Source::Gemspec` gems that come from the `gemspec` DSL method are allowed to have conflicts. It appears projects, such as rails, were taking advantage of that fact. Since `stub_entrypoints` is called whenever `Bundler.setup` is run, this is essentially us 'activating' all of the gems in the bundle. Since everything is eagerly activated, it should be impossible for there to ever be any unresolved dependencies, and thus `Gem.finish_resolve` should always be a no-op anyways. We can save CPU cycles and keep our special resolution behavior for `Source::Gemspec` by just acknowledging that `Gem.finish_resolve` should always be a no-op once the bundle has been setup.
-rw-r--r--lib/bundler/rubygems_integration.rb4
-rw-r--r--spec/install/gemfile/gemspec_spec.rb24
2 files changed, 28 insertions, 0 deletions
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index 693f4dd086..85c653bee6 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -698,6 +698,10 @@ module Bundler
Gem.post_reset do
Gem::Specification.all = specs
end
+
+ redefine_method((class << Gem; self; end), :finish_resolve) do |*|
+ []
+ end
end
def all_specs
diff --git a/spec/install/gemfile/gemspec_spec.rb b/spec/install/gemfile/gemspec_spec.rb
index e2534be1ad..1ea613c9d2 100644
--- a/spec/install/gemfile/gemspec_spec.rb
+++ b/spec/install/gemfile/gemspec_spec.rb
@@ -231,6 +231,30 @@ RSpec.describe "bundle install from an existing gemspec" do
expect(the_bundle).to include_gems "foo 1.0.0"
end
+ it "does not break Gem.finish_resolve with conflicts", :rubygems => ">= 2" do
+ build_lib("foo", :path => tmp.join("foo")) do |s|
+ s.version = "1.0.0"
+ s.add_dependency "bar", "= 1.0.0"
+ end
+ build_repo2 do
+ build_gem "deps" do |s|
+ s.add_dependency "foo", "= 0.0.1"
+ end
+ build_gem "foo", "0.0.1"
+ end
+
+ install_gemfile! <<-G
+ source "file://#{gem_repo2}"
+ gem "deps"
+ gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
+ G
+
+ expect(the_bundle).to include_gems "foo 1.0.0"
+
+ run! "Gem.finish_resolve; puts 'WIN'"
+ expect(out).to eq("WIN")
+ end
+
context "in deployment mode" do
context "when the lockfile was not updated after a change to the gemspec's dependencies" do
it "reports that installation failed" do