diff options
author | The Bundler Bot <bot@bundler.io> | 2017-05-09 03:42:07 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-05-09 03:42:07 +0000 |
commit | a1925cb18c58232ba009df01478b65dfe43d51ba (patch) | |
tree | 829cd0a2acc72c4a00b8b2475db8cdf617df5a20 | |
parent | 47e7dd0e93a11b40fa982aaef5eb7d35cb7c2717 (diff) | |
parent | aeec3437f20c70624d778a7c40e0525dd69d3933 (diff) | |
download | bundler-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.rb | 4 | ||||
-rw-r--r-- | spec/install/gemfile/gemspec_spec.rb | 24 |
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 |