summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Bundler Bot <bot@bundler.io>2018-09-13 04:30:32 +0000
committerThe Bundler Bot <bot@bundler.io>2018-09-13 04:30:32 +0000
commit87f49b2dc000b38776e6a73924e63ec090d53062 (patch)
tree4f7e9d3ae6ceca613baf38c87ae8ea47357115c9
parent368d7594adbdf83032719011d7608545faf2d942 (diff)
parent7aa2639f79f019e0cff55bd27140360fe34c0eb7 (diff)
downloadbundler-87f49b2dc000b38776e6a73924e63ec090d53062.tar.gz
Auto merge of #6695 - bundler:segiddins/6684-gvp-prefer-non-pres, r=colby-swandale
[GemVersionPromoter] Prefer non-pre-release versions ### What was the end-user problem that led to this PR? The problem was `bundle update --patch` could cause a prerelease to be resolved, when it shouldn't have been. Closes #6684. ### What was your diagnosis of the problem? My diagnosis was the resolver moved pre's to be first when no pre requirement was specified, but then the GVP did its own sorting. ### What is your fix for the problem, implemented in this PR? My fix was to re-implement that "pre's go first unless they were explicitly requested" logic in the GVP. ### Why did you choose this fix out of the possible options? I chose this fix because it allows the GVP to properly sort versions, making it entirely correct without dependence upon the resolver.
-rw-r--r--lib/bundler/gem_version_promoter.rb12
-rw-r--r--lib/bundler/resolver.rb11
-rw-r--r--spec/resolver/basic_spec.rb12
-rw-r--r--spec/support/indexes.rb1
4 files changed, 31 insertions, 5 deletions
diff --git a/lib/bundler/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb
index 8d412c2cc0..ed950ad28b 100644
--- a/lib/bundler/gem_version_promoter.rb
+++ b/lib/bundler/gem_version_promoter.rb
@@ -24,6 +24,8 @@ module Bundler
# existing in the referenced source.
attr_accessor :strict
+ attr_accessor :prerelease_specified
+
# Given a list of locked_specs and a list of gems to unlock creates a
# GemVersionPromoter instance.
#
@@ -39,6 +41,7 @@ module Bundler
@locked_specs = locked_specs
@unlock_gems = unlock_gems
@sort_versions = {}
+ @prerelease_specified = {}
end
# @param value [Symbol] One of three Symbols: :major, :minor or :patch.
@@ -123,6 +126,15 @@ module Bundler
result = spec_groups.sort do |a, b|
@a_ver = a.version
@b_ver = b.version
+
+ unless @prerelease_specified[@gem_name]
+ a_pre = @a_ver.prerelease?
+ b_pre = @b_ver.prerelease?
+
+ next -1 if a_pre && !b_pre
+ next 1 if b_pre && !a_pre
+ end
+
if major?
@a_ver <=> @b_ver
elsif either_version_older_than_locked
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index a6c26ffc6b..fac28ced90 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -43,7 +43,7 @@ module Bundler
end
def start(requirements)
- @prerelease_specified = {}
+ @gem_version_promoter.prerelease_specified = @prerelease_specified = {}
requirements.each {|dep| @prerelease_specified[dep.name] ||= dep.prerelease? }
verify_gemfile_dependencies_are_found!(requirements)
@@ -108,16 +108,17 @@ module Bundler
index = index_for(dependency)
results = index.search(dependency, @base[dependency.name])
- unless @prerelease_specified[dependency.name]
+ if vertex = @base_dg.vertex_named(dependency.name)
+ locked_requirement = vertex.payload.requirement
+ end
+
+ if !@prerelease_specified[dependency.name] && (!@use_gvp || locked_requirement.nil?)
# Move prereleases to the beginning of the list, so they're considered
# last during resolution.
pre, results = results.partition {|spec| spec.version.prerelease? }
results = pre + results
end
- if vertex = @base_dg.vertex_named(dependency.name)
- locked_requirement = vertex.payload.requirement
- end
spec_groups = if results.any?
nested = []
results.each do |spec|
diff --git a/spec/resolver/basic_spec.rb b/spec/resolver/basic_spec.rb
index a2d5e13377..9f92303447 100644
--- a/spec/resolver/basic_spec.rb
+++ b/spec/resolver/basic_spec.rb
@@ -87,6 +87,18 @@ RSpec.describe "Resolving" do
should_resolve_as %w[activesupport-3.0.0.beta actionpack-3.0.0.beta rack-1.1 rack-mount-0.6]
end
+ it "prefers non-pre-releases when doing conservative updates" do
+ @index = build_index do
+ gem "mail", "2.7.0"
+ gem "mail", "2.7.1.rc1"
+ gem "RubyGems\0", Gem::VERSION
+ end
+ dep "mail"
+ @locked = locked ["mail", "2.7.0"]
+ @base = locked
+ should_conservative_resolve_and_include [:patch], [], ["mail-2.7.0"]
+ end
+
it "raises an exception if a child dependency is not resolved" do
@index = a_unresovable_child_index
dep "chef_app_error"
diff --git a/spec/support/indexes.rb b/spec/support/indexes.rb
index 5f6c515735..b76f493d01 100644
--- a/spec/support/indexes.rb
+++ b/spec/support/indexes.rb
@@ -66,6 +66,7 @@ module Spec
search = Bundler::GemVersionPromoter.new(@locked, unlock).tap do |s|
s.level = opts.first
s.strict = opts.include?(:strict)
+ s.prerelease_specified = Hash[@deps.map {|d| [d.name, d.requirement.prerelease?] }]
end
should_resolve_and_include specs, [@base, search]
end