From 363f3076c3e8beafd852b2948ead86c3d6b07b02 Mon Sep 17 00:00:00 2001 From: Tim Moore Date: Sat, 25 Apr 2015 08:33:58 +1000 Subject: Replace locked gem sources with Gemfile equivalents. Previously, an up-to-date lock file would retain the aggregate gem source on all dependencies, so if the gems were not installed locally, you'd get an ambiguous gem warning and possibly the wrong source selected. Fixes #3585 --- lib/bundler/definition.rb | 11 ++++++----- spec/install/gems/sources_spec.rb | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index e9d5d0b6..86dbfba2 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -184,11 +184,10 @@ module Bundler # @return [SpecSet] resolved dependencies def resolve @resolve ||= begin + last_resolve = converge_locked_specs if Bundler.settings[:frozen] || (!@unlocking && nothing_changed?) - @locked_specs + last_resolve else - last_resolve = converge_locked_specs - # Run a resolve against the locally available gems last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve) end @@ -521,7 +520,9 @@ module Bundler converged = [] @locked_specs.each do |s| - s.source = sources.get(s.source) + # Replace the locked dependency's source with the equivalent source from the Gemfile + dep = @dependencies.find { |dep| s.satisfies?(dep) } + s.source = (dep && dep.source) || sources.get(s.source) # Don't add a spec to the list if its source is expired. For example, # if you change a Git gem to Rubygems. @@ -569,7 +570,7 @@ module Bundler end def satisfies_locked_spec?(dep) - @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source == dep.source) } + @locked_specs.any? { |s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) } end def expanded_dependencies diff --git a/spec/install/gems/sources_spec.rb b/spec/install/gems/sources_spec.rb index 45e3a43e..731f1402 100644 --- a/spec/install/gems/sources_spec.rb +++ b/spec/install/gems/sources_spec.rb @@ -229,6 +229,40 @@ describe "bundle install with gems on multiple sources" do should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0") end end + + context "and only the dependency is pinned" do + before do + # need this to be broken to check for correct source ordering + build_repo gem_repo2 do + build_gem "rack", "1.0.0" do |s| + s.write "lib/rack.rb", "RACK = 'FAIL'" + end + end + + gemfile <<-G + source "file://#{gem_repo3}" # contains depends_on_rack + source "file://#{gem_repo2}" # contains broken rack + + gem "depends_on_rack" # installed from gem_repo3 + gem "rack", :source => "file://#{gem_repo1}" + G + end + + it "installs the dependency from the pinned source without warning" do + bundle :install + + expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.") + should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0") + + # In https://github.com/bundler/bundler/issues/3585 this failed + # when there is already a lock file, and the gems are missing, so try again + system_gems [] + bundle :install + + expect(out).not_to include("Warning: the gem 'rack' was found in multiple sources.") + should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0") + end + end end end -- cgit v1.2.3