require 'pub_grub/version_range' module PubGrub class VersionConstraint attr_reader :package, :range # @param package [PubGrub::Package] # @param range [PubGrub::VersionRange] def initialize(package, range: nil) @package = package @range = range end class << self def exact(package, version) range = VersionRange.new(min: version, max: version, include_min: true, include_max: true) new(package, range: range) end def any(package) new(package, range: VersionRange.any) end def empty(package) new(package, range: VersionRange.empty) end end def intersect(other) unless package == other.package raise ArgumentError, "Can only intersect between VersionConstraint of the same package" end self.class.new(package, range: range.intersect(other.range)) end def union(other) unless package == other.package raise ArgumentError, "Can only intersect between VersionConstraint of the same package" end self.class.new(package, range: range.union(other.range)) end def invert new_range = range.invert self.class.new(package, range: new_range) end def difference(other) intersect(other.invert) end def allows_all?(other) range.allows_all?(other.range) end def allows_any?(other) range.intersects?(other.range) end def subset?(other) other.allows_all?(self) end def overlap?(other) other.allows_any?(self) end def disjoint?(other) !overlap?(other) end def relation(other) if subset?(other) :subset elsif overlap?(other) :overlap else :disjoint end end def to_s(allow_every: false) if package == Package.root "root" elsif allow_every && any? "every version of #{package.name}" else "#{package.name} #{constraint_string}" end end def constraint_string if any? ">= 0" else range.to_s end end def empty? range.empty? end # Does this match every version of the package def any? range.any? end def inspect "#<#{self.class} #{self}>" end end end