From 25bf713bf071665b02e4817aeece7951e7bf5b22 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 5198a8e3a4..2b15b15573 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 @@ -518,7 +517,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. @@ -566,7 +567,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 847f741162..86d23c4ed2 100644 --- a/spec/install/gems/sources_spec.rb +++ b/spec/install/gems/sources_spec.rb @@ -219,6 +219,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.1