lib/bundler/patch/conservative_resolver.rb in bundler-patch-0.9.0 vs lib/bundler/patch/conservative_resolver.rb in bundler-patch-0.10.0
- old
+ new
@@ -1,15 +1,14 @@
module Bundler::Patch
class ConservativeResolver < Bundler::Resolver
attr_accessor :locked_specs, :gems_to_update, :strict, :minor_preferred, :prefer_minimal
def initialize(index, source_requirements, base)
- # hack for 1.10 and 1.11+ support
case Bundler::Resolver.instance_method(:initialize).arity
- when 3
+ when 3 # 1.9 1.10
super(index, source_requirements, base)
- when 4
+ when 4 # 1.11 1.12
super(index, source_requirements, base, nil)
end
end
def search_for(dependency)
@@ -72,50 +71,83 @@
end
# reminder: sort still filters anything older than locked version
def sort_specs(specs, locked_spec)
return specs unless locked_spec
- gem_name = locked_spec.name
- locked_version = locked_spec.version
+ @gem_name = locked_spec.name
+ @locked_version = locked_spec.version
- filtered = specs.select { |s| s.first.version >= locked_version }
+ filtered = specs.select { |s| s.first.version >= @locked_version }
- filtered.sort do |a, b|
- a_ver = a.first.version
- b_ver = b.first.version
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
- new_version = gem_patch ? gem_patch.new_version : nil
+ @gem_patch = @gems_to_update.gem_patch_for(@gem_name)
+ @new_version = @gem_patch ? @gem_patch.new_version : nil
+
+ result = filtered.sort do |a, b|
+ @a_ver = a.first.version
+ @b_ver = b.first.version
case
- when a_ver.segments[0] != b_ver.segments[0]
- b_ver <=> a_ver
- when !@minor_preferred && (a_ver.segments[1] != b_ver.segments[1])
- b_ver <=> a_ver
- when @prefer_minimal && !@gems_to_update.unlocking_gem?(gem_name)
- b_ver <=> a_ver
- when @prefer_minimal && @gems_to_update.unlocking_gem?(gem_name) &&
- (![a_ver, b_ver].include?(locked_version) &&
- (!new_version || (new_version && a_ver >= new_version && b_ver >= new_version)))
- b_ver <=> a_ver
+ when segments_do_not_match(:major)
+ @b_ver <=> @a_ver
+ when !@minor_preferred && segments_do_not_match(:minor)
+ @b_ver <=> @a_ver
+ when @prefer_minimal && !unlocking_gem?
+ @b_ver <=> @a_ver
+ when @prefer_minimal && unlocking_gem? &&
+ (neither_version_matches(@locked_version) &&
+ (!@new_version || both_versions_gt_or_equal_to_version(@new_version)))
+ @b_ver <=> @a_ver
else
- a_ver <=> b_ver
+ @a_ver <=> @b_ver
end
- end.tap do |result|
- if @gems_to_update.unlocking_gem?(gem_name)
- gem_patch = @gems_to_update.gem_patch_for(gem_name)
- if gem_patch && gem_patch.new_version && @prefer_minimal
- move_version_to_end(specs, gem_patch.new_version, result)
- end
- else
- move_version_to_end(specs, locked_version, result)
- end
end
+ post_sort(result)
end
- def move_version_to_end(specs, version, result)
- spec_group = specs.detect { |s| s.first.version.to_s == version.to_s }
- if spec_group
- result.reject! { |s| s.first.version.to_s === version.to_s }
- result << spec_group
+ def post_sort(result)
+ unless unlocking_gem?
+ result = move_version_to_end(result, @locked_version)
end
+
+ if @new_version && unlocking_gem? && segments_match(:major, @new_version, @locked_version)
+ if @prefer_minimal || (!@prefer_minimal && (result.last.first.version < @new_version))
+ result = move_version_to_end(result, @new_version)
+ end
+ end
+
+ result
+ end
+
+ def unlocking_gem?
+ @gems_to_update.unlocking_gem?(@gem_name)
+ end
+
+ def either_version_older_than_locked(locked_version)
+ @a_ver < locked_version || @b_ver < locked_version
+ end
+
+ def segments_match(level, a_ver=@a_ver, b_ver=@b_ver)
+ !segments_do_not_match(level, a_ver, b_ver)
+ end
+
+ def segments_do_not_match(level, a_ver=@a_ver, b_ver=@b_ver)
+ index = [:major, :minor].index(level)
+ a_ver.segments[index] != b_ver.segments[index]
+ end
+
+ def neither_version_matches(match_version)
+ !one_version_matches(match_version)
+ end
+
+ def one_version_matches(match_version)
+ [@a_ver, @b_ver].include?(match_version)
+ end
+
+ def both_versions_gt_or_equal_to_version(version)
+ version && @a_ver >= version && @b_ver >= version
+ end
+
+ def move_version_to_end(result, version)
+ move, keep = result.partition { |s| s.first.version.to_s == version.to_s }
+ keep.concat(move)
end
end
end