Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Commit

Permalink
Fix computation of version range emptiness
Browse files Browse the repository at this point in the history
  • Loading branch information
segiddins committed Aug 7, 2018
1 parent a220ba5 commit 017cc4d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
56 changes: 51 additions & 5 deletions lib/bundler/version_ranges.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,42 @@ module VersionRanges
NEq = Struct.new(:version)
ReqR = Struct.new(:left, :right)
class ReqR
Endpoint = Struct.new(:version, :inclusive)
Endpoint = Struct.new(:version, :inclusive) do
def <=>(other)
if version.equal?(INFINITY)
return 0 if other.version.equal?(INFINITY)
return 1
elsif other.version.equal?(INFINITY)
return -1
end

comp = version <=> other.version
return comp unless comp.zero?

if inclusive && !other.inclusive
1
elsif !inclusive && other.inclusive
-1
else
0
end
end
end

def to_s
"#{left.inclusive ? "[" : "("}#{left.version}, #{right.version}#{right.inclusive ? "]" : ")"}"
end
INFINITY = Object.new.freeze
INFINITY = begin
inf = Object.new
def inf.to_s
"∞"
end
def inf.<=>(other)
return 0 if other.equal?(self)
1
end
inf.freeze
end
ZERO = Gem::Version.new("0.a")

def cover?(v)
Expand All @@ -32,6 +63,15 @@ def single?
left.version == right.version
end

def <=>(other)
return -1 if other.equal?(INFINITY)

comp = left <=> other.left
return comp unless comp.zero?

right <=> other.right
end

UNIVERSAL = ReqR.new(ReqR::Endpoint.new(Gem::Version.new("0.a"), true), ReqR::Endpoint.new(ReqR::INFINITY, false)).freeze
end

Expand All @@ -57,7 +97,7 @@ def self.for(requirement)
end.uniq
ranges, neqs = ranges.partition {|r| !r.is_a?(NEq) }

[ranges.sort_by {|range| [range.left.version, range.left.inclusive ? 0 : 1] }, neqs.map(&:version)]
[ranges.sort, neqs.map(&:version)]
end

def self.empty?(ranges, neqs)
Expand All @@ -66,8 +106,14 @@ def self.empty?(ranges, neqs)
next false if curr_range.single? && neqs.include?(curr_range.left.version)
next curr_range if last_range.right.version == ReqR::INFINITY
case last_range.right.version <=> curr_range.left.version
when 1 then next curr_range
when 0 then next(last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version) && curr_range)
# higher
when 1 then next ReqR.new(curr_range.left, last_range.right)
# equal
when 0
if last_range.right.inclusive && curr_range.left.inclusive && !neqs.include?(curr_range.left.version)
ReqR.new(curr_range.left, [curr_range.right, last_range.right].max)
end
# lower
when -1 then next false
end
end
Expand Down
3 changes: 3 additions & 0 deletions spec/bundler/version_ranges_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
include_examples "empty?", false, ">= 1.0.0", "< 2.0.0"
include_examples "empty?", false, "~> 1"
include_examples "empty?", false, "~> 2.0", "~> 2.1"
include_examples "empty?", true, ">= 4.1.0", "< 5.0", "= 5.2.1"
include_examples "empty?", true, "< 5.0", "< 5.3", "< 6.0", "< 6", "= 5.2.0", "> 2", ">= 3.0", ">= 3.1", ">= 3.2", ">= 4.0.0", ">= 4.1.0", ">= 4.2.0", ">= 4.2", ">= 4"
include_examples "empty?", true, "!= 1", "< 2", "> 2"
include_examples "empty?", true, "!= 1", "<= 1", ">= 1"
include_examples "empty?", true, "< 2", "> 2"
include_examples "empty?", true, "< 2", "> 2", "= 2"
include_examples "empty?", true, "= 1", "!= 1"
include_examples "empty?", true, "= 1", "= 2"
include_examples "empty?", true, "= 1", "~> 2"
Expand Down

0 comments on commit 017cc4d

Please sign in to comment.