diff options
author | Tim Moore <tmoore@incrementalism.net> | 2015-04-25 08:33:58 +1000 |
---|---|---|
committer | Tim Moore <tmoore@incrementalism.net> | 2015-04-25 10:12:37 +1000 |
commit | 25bf713bf071665b02e4817aeece7951e7bf5b22 (patch) | |
tree | f4337256a093c6d511d8e65f3c0014da506f4beb | |
parent | 1d7ab322984a601557953a1a236d57d3f471cc97 (diff) | |
download | bundler-25bf713bf071665b02e4817aeece7951e7bf5b22.tar.gz |
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
-rw-r--r-- | lib/bundler/definition.rb | 11 | ||||
-rw-r--r-- | 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 |