1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
module SemanticRange
class Comparator
attr_reader :semver, :operator, :value
def initialize(comp, loose)
comp = comp.value if comp.is_a?(Comparator)
@loose = loose
parse(comp)
@value = @semver == ANY ? '' : @operator + @semver.version
end
def to_s
@value
end
def test(version)
return true if @semver == ANY
version = Version.new(version, @loose) if version.is_a?(String)
SemanticRange.cmp(version, @operator, @semver, loose: @loose)
end
def parse(comp)
m = comp.match(@loose ? COMPARATORLOOSE : COMPARATOR)
raise InvalidComparator.new(comp) unless m
@operator = m[1]
@operator = '' if @operator == '='
@semver = !m[2] ? ANY : Version.new(m[2], loose: @loose)
end
def intersects?(comp, loose: false, platform: nil)
comp = Comparator.new(comp, loose)
if @operator == ''
range_b = Range.new(comp.value, loose: loose, platform: platform)
SemanticRange.satisfies?(@value, range_b, loose: loose, platform: platform)
elsif comp.operator == ''
range_a = Range.new(@value, loose: loose, platform: platform)
SemanticRange.satisfies?(comp.semver, range_a, loose: loose, platform: platform)
else
same_direction_increasing = (@operator == '>=' || @operator == '>') && (comp.operator == '>=' || comp.operator == '>')
same_direction_decreasing = (@operator == '<=' || @operator == '<') && (comp.operator == '<=' || comp.operator == '<')
same_version = @semver.raw == comp.semver.raw
different_directions_inclusive = (@operator == '>=' || @operator == '<=') && (comp.operator == '>=' || comp.operator == '<=')
opposite_directions_lte = SemanticRange.cmp(@semver, '<', comp.semver, loose: loose) &&
((@operator == '>=' || @operator == '>') && (comp.operator == '<=' || comp.operator == '<'))
opposite_directions_gte = SemanticRange.cmp(@semver, '>', comp.semver, loose: loose) &&
((@operator == '<=' || @operator == '<') && (comp.operator == '>=' || comp.operator == '>'))
same_direction_increasing || same_direction_decreasing || (same_version && different_directions_inclusive) ||
opposite_directions_lte || opposite_directions_gte
end
end
def satisfies_range?(range, loose: false, platform: nil)
range = Range.new(range, loose: loose, platform: platform)
range.set.any? do |comparators|
comparators.all? do |comparator|
intersects?(comparator, loose: loose, platform: platform)
end
end
end
# Support for older non-inquisitive method versions
alias_method :intersects, :intersects?
alias_method :satisfies_range, :satisfies_range?
end
end
|