summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-08-20 09:36:47 +0900
committerHomu <homu@barosl.com>2016-08-20 09:36:47 +0900
commit9fe7b6cfbd9583cbc6efdb636fa2ae63b57b3320 (patch)
tree4a98ec0b9cb79f29831c950b253840829af53a5a
parent54ff7a4fb827ec36d5cac2fac843993f28b19077 (diff)
parent7432cd5effb174316c281aefa7907929d4dde3bc (diff)
downloadbundler-9fe7b6cfbd9583cbc6efdb636fa2ae63b57b3320.tar.gz
Auto merge of #4893 - bundler:seg-block-update-regressions, r=indirect
Block resolving to older versions during an update This is currently behind the only_update_to_newer_versions setting Closes https://github.com/bundler/bundler/issues/4511. See https://github.com/bundler/bundler/issues/4856 and https://github.com/bundler/bundler/issues/4871
-rw-r--r--.rubocop.yml3
-rw-r--r--lib/bundler/definition.rb10
-rw-r--r--lib/bundler/resolver.rb7
-rw-r--r--lib/bundler/settings.rb1
-rw-r--r--spec/commands/update_spec.rb36
5 files changed, 53 insertions, 4 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index cbce695fbd..b027d4cf54 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -119,6 +119,9 @@ Metrics/AbcSize:
Metrics/CyclomaticComplexity:
Enabled: false
+Metrics/ParameterLists:
+ Enabled: false
+
# It will be obvious which code is complex, Rubocop should only lint simple
# rules for us.
Metrics/PerceivedComplexity:
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index ee966e7164..2d328e0de1 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -249,7 +249,7 @@ module Bundler
else
# Run a resolve against the locally available gems
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
- last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, ruby_version, gem_version_promoter)
+ last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, ruby_version, gem_version_promoter, additional_base_requirements_for_resolve)
end
end
end
@@ -812,5 +812,13 @@ module Bundler
requires
end
end
+
+ def additional_base_requirements_for_resolve
+ return [] unless @locked_gems && Bundler.settings[:only_update_to_newer_versions]
+ @locked_gems.specs.reduce({}) do |requirements, locked_spec|
+ requirements[locked_spec.name] = Gem::Dependency.new(locked_spec.name, ">= #{locked_spec.version}")
+ requirements
+ end.values
+ end
end
end
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 9d947cc9f9..10d5404028 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -175,14 +175,14 @@ module Bundler
# ==== Returns
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
# collection of gemspecs is returned. Otherwise, nil is returned.
- def self.resolve(requirements, index, source_requirements = {}, base = [], ruby_version = nil, gem_version_promoter = GemVersionPromoter.new)
+ def self.resolve(requirements, index, source_requirements = {}, base = [], ruby_version = nil, gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [])
base = SpecSet.new(base) unless base.is_a?(SpecSet)
- resolver = new(index, source_requirements, base, ruby_version, gem_version_promoter)
+ resolver = new(index, source_requirements, base, ruby_version, gem_version_promoter, additional_base_requirements)
result = resolver.start(requirements)
SpecSet.new(result)
end
- def initialize(index, source_requirements, base, ruby_version, gem_version_promoter)
+ def initialize(index, source_requirements, base, ruby_version, gem_version_promoter, additional_base_requirements)
@index = index
@source_requirements = source_requirements
@base = base
@@ -190,6 +190,7 @@ module Bundler
@search_for = {}
@base_dg = Molinillo::DependencyGraph.new
@base.each {|ls| @base_dg.add_vertex(ls.name, Dependency.new(ls.name, ls.version), true) }
+ additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@ruby_version = ruby_version
@gem_version_promoter = gem_version_promoter
end
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 2a04805f92..365d20adda 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -16,6 +16,7 @@ module Bundler
major_deprecations
no_install
no_prune
+ only_update_to_newer_versions
plugins
silence_root_warning
).freeze
diff --git a/spec/commands/update_spec.rb b/spec/commands/update_spec.rb
index 19fbb8388c..8a9867d1e9 100644
--- a/spec/commands/update_spec.rb
+++ b/spec/commands/update_spec.rb
@@ -72,6 +72,42 @@ describe "bundle update" do
end
end
+ describe "when a possible resolve requires an older version of a locked gem" do
+ context "and only_update_to_newer_versions is set" do
+ before do
+ bundle! "config only_update_to_newer_versions true"
+ end
+ it "does not go to an older version" do
+ build_repo4 do
+ build_gem "a" do |s|
+ s.add_dependency "b"
+ s.add_dependency "c"
+ end
+ build_gem "b"
+ build_gem "c"
+ build_gem "c", "2.0"
+ end
+
+ install_gemfile! <<-G
+ source "file:#{gem_repo4}"
+ gem "a"
+ G
+
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+
+ update_repo4 do
+ build_gem "b", "2.0" do |s|
+ s.add_dependency "c", "< 2"
+ end
+ end
+
+ bundle! "update"
+
+ expect(the_bundle).to include_gems("a 1.0", "b 1.0", "c 2.0")
+ end
+ end
+ end
+
describe "with --local option" do
it "doesn't hit repo2" do
FileUtils.rm_rf(gem_repo2)