diff options
author | Homu <homu@barosl.com> | 2016-08-20 09:36:47 +0900 |
---|---|---|
committer | Homu <homu@barosl.com> | 2016-08-20 09:36:47 +0900 |
commit | 9fe7b6cfbd9583cbc6efdb636fa2ae63b57b3320 (patch) | |
tree | 4a98ec0b9cb79f29831c950b253840829af53a5a | |
parent | 54ff7a4fb827ec36d5cac2fac843993f28b19077 (diff) | |
parent | 7432cd5effb174316c281aefa7907929d4dde3bc (diff) | |
download | bundler-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.yml | 3 | ||||
-rw-r--r-- | lib/bundler/definition.rb | 10 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 7 | ||||
-rw-r--r-- | lib/bundler/settings.rb | 1 | ||||
-rw-r--r-- | spec/commands/update_spec.rb | 36 |
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) |