class Bundler::GemVersionPromoter

to the resolution engine to select the best version.
available dependency versions as found in its index, before returning it to
Primarily designed to work with Resolver which will provide it the list of
Gem to update to based on the requested level (patch, minor, major).
This class contains all of the logic for determining the next version of a

def either_version_older_than_locked?(a, b, locked_version)

def either_version_older_than_locked?(a, b, locked_version)
  a.version < locked_version || b.version < locked_version
end

def filter_versions(package, specs)

Returns:
  • (Specification) - A new instance of the Specification Array

Parameters:
  • specs (Specification) -- An array of Specifications for the package.
  • package (Resolver::Package) -- The package being resolved.
def filter_versions(package, specs)
  return specs unless strict
  locked_version = package.locked_version
  return specs if locked_version.nil? || major?
  specs.select do |spec|
    gsv = spec.version
    must_match = minor? ? [0] : [0, 1]
    all_match = must_match.all? {|idx| gsv.segments[idx] == locked_version.segments[idx] }
    all_match && gsv >= locked_version
  end
end

def initialize

Returns:
  • (GemVersionPromoter) -
def initialize
  @level = :major
  @strict = false
  @pre = false
end

def level=(value)

Parameters:
  • value (Symbol) -- One of three Symbols: :major, :minor or :patch.
def level=(value)
  v = case value
      when String, Symbol
        value.to_sym
  end
  raise ArgumentError, "Unexpected level #{v}. Must be :major, :minor or :patch" unless [:major, :minor, :patch].include?(v)
  @level = v
end

def major?

Returns:
  • (bool) - Convenience method for testing value of level variable.
def major?
  level == :major
end

def minor?

Returns:
  • (bool) - Convenience method for testing value of level variable.
def minor?
  level == :minor
end

def move_version_to_beginning(result, version)

def move_version_to_beginning(result, version)
  move, keep = result.partition {|s| s.version.to_s == version.to_s }
  move.concat(keep)
end

def post_sort(result, unlock, locked_version)

as not all elements are compared against each other.
Specific version moves can't always reliably be done during sorting
def post_sort(result, unlock, locked_version)
  # default :major behavior in Bundler does not do this
  return result if major?
  if unlock || locked_version.nil?
    result
  else
    move_version_to_beginning(result, locked_version)
  end
end

def pre?

Returns:
  • (bool) - Convenience method for testing value of pre variable.
def pre?
  pre == true
end

def segments_do_not_match?(a, b, level)

def segments_do_not_match?(a, b, level)
  index = [:major, :minor].index(level)
  a.segments[index] != b.segments[index]
end

def sort_versions(package, specs)

Returns:
  • (Specification) - A new instance of the Specification Array sorted.

Parameters:
  • specs (Specification) -- An array of Specifications for the package.
  • package (Resolver::Package) -- The package being resolved.
def sort_versions(package, specs)
  locked_version = package.locked_version
  result = specs.sort do |a, b|
    unless package.prerelease_specified? || pre?
      a_pre = a.prerelease?
      b_pre = b.prerelease?
      next 1 if a_pre && !b_pre
      next -1 if b_pre && !a_pre
    end
    if major? || locked_version.nil?
      b <=> a
    elsif either_version_older_than_locked?(a, b, locked_version)
      b <=> a
    elsif segments_do_not_match?(a, b, :major)
      a <=> b
    elsif !minor? && segments_do_not_match?(a, b, :minor)
      a <=> b
    else
      b <=> a
    end
  end
  post_sort(result, package.unlock?, locked_version)
end