diff options
author | The Bundler Bot <bot@bundler.io> | 2017-05-09 03:42:07 +0000 |
---|---|---|
committer | Samuel Giddins <segiddins@segiddins.me> | 2017-05-10 12:26:59 -0500 |
commit | 49bbdebf91f4684e69190ae7c52c0bcc437574e6 (patch) | |
tree | 0d435dd1bce06d18937bc237a0d0e2b873bf2dd1 | |
parent | a493113b049ab7768b7947daa7634827216141cd (diff) | |
download | bundler-49bbdebf91f4684e69190ae7c52c0bcc437574e6.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.
(cherry picked from commit a1925cb18c58232ba009df01478b65dfe43d51ba)
-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 7283a326dd..e33ae41b50 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 |