Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Block resolving to older versions during an update #4893

Merged
merged 1 commit into from
Aug 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 9 additions & 1 deletion lib/bundler/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def resolve
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
Expand Down Expand Up @@ -812,5 +812,13 @@ def compute_requires
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
7 changes: 4 additions & 3 deletions lib/bundler/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,22 @@ def __dependencies
# ==== 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
@resolver = Molinillo::Resolver.new(self, self)
@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
Expand Down
1 change: 1 addition & 0 deletions lib/bundler/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class Settings
major_deprecations
no_install
no_prune
only_update_to_newer_versions
plugins
silence_root_warning
).freeze
Expand Down
36 changes: 36 additions & 0 deletions spec/commands/update_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,42 @@
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)
Expand Down