diff options
-rw-r--r-- | lib/bundler/gem_version_promoter.rb | 12 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 11 | ||||
-rw-r--r-- | spec/resolver/basic_spec.rb | 12 | ||||
-rw-r--r-- | spec/support/indexes.rb | 1 |
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 |