class SemVer

We need to subclass Numeric to force range comparisons not to try to iterate over SemVer and instead use numeric comparisons (eg >, <, >=, <=) Ruby 1.8 already did this for all ranges, but Ruby 1.9 changed range include behavior

Constants

MAX
MIN
SIMPLE_RANGE
VERSION

Attributes

major[R]
minor[R]
special[R]
tiny[R]

Public Class Methods

[](range) click to toggle source
# File lib/semver.rb, line 24
def self.[](range)
  range.gsub(/([><=])\s+/, '\1').split(/\b\s+(?!-)/).map do |r|
    case r
    when SemVer::VERSION
      SemVer.new(pre(r)) .. SemVer.new(r)
    when SemVer::SIMPLE_RANGE
      r += ".0" unless SemVer.valid?(r.gsub(/x/, '0'))
      SemVer.new(r.gsub(/x/, '0'))...SemVer.new(r.gsub(/(\d+)\.x/) { "#{$1.to_i + 1}.0" } + '-')
    when /\s+-\s+/
      a, b = r.split(/\s+-\s+/)
      SemVer.new(pre(a)) .. SemVer.new(b)
    when /^~/
      ver = r.sub(/~/, '').split('.').map(&:to_i)
      start = (ver + [0] * (3 - ver.length)).join('.')

      ver.pop unless ver.length == 1
      ver[-1] = ver.last + 1

      finish = (ver + [0] * (3 - ver.length)).join('.')
      SemVer.new(pre(start)) ... SemVer.new(pre(finish))
    when /^>=/
      ver = r.sub(/^>=/, '')
      SemVer.new(pre(ver)) .. SemVer::MAX
    when /^<=/
      ver = r.sub(/^<=/, '')
      SemVer::MIN .. SemVer.new(ver)
    when /^>/
      if r =~ /-/
        ver = [r[1..-1]]
      else
        ver = r.sub(/^>/, '').split('.').map(&:to_i)
        ver[2] = ver.last + 1
      end
      SemVer.new(ver.join('.') + '-') .. SemVer::MAX
    when /^</
      ver = r.sub(/^</, '')
      SemVer::MIN ... SemVer.new(pre(ver))
    else
      (1..1)
    end
  end.inject { |a,e| a & e }
end
find_matching(pattern, versions) click to toggle source
# File lib/semver.rb, line 16
def self.find_matching(pattern, versions)
  versions.select { |v| v.matched_by?("#{pattern}") }.sort.last
end
new(ver) click to toggle source
# File lib/semver.rb, line 69
def initialize(ver)
  unless SemVer.valid?(ver)
    raise ArgumentError.new("Invalid version string '#{ver}'!")
  end

  @major, @minor, @tiny, @special = VERSION.match(ver).captures.map do |x|
    # Because Kernel#Integer tries to interpret hex and octal strings, which
    # we specifically do not want, and which cannot be overridden in 1.8.7.
    Float(x).to_i rescue x
  end
end
pre(vstring) click to toggle source
# File lib/semver.rb, line 20
def self.pre(vstring)
  vstring =~ /-/ ? vstring : vstring + '-'
end
valid?(ver) click to toggle source
# File lib/semver.rb, line 12
def self.valid?(ver)
  VERSION =~ ver
end

Public Instance Methods

<=>(other) click to toggle source
# File lib/semver.rb, line 81
def <=>(other)
  other = SemVer.new("#{other}") unless other.is_a? SemVer
  return self.major <=> other.major unless self.major == other.major
  return self.minor <=> other.minor unless self.minor == other.minor
  return self.tiny  <=> other.tiny  unless self.tiny  == other.tiny

  return 0  if self.special  == other.special
  return 1  if self.special  == ''
  return -1 if other.special == ''

  return self.special <=> other.special
end
inspect() click to toggle source
# File lib/semver.rb, line 113
def inspect
  @vstring || "v#{@major}.#{@minor}.#{@tiny}#{@special}"
end
Also aliased as: to_s
matched_by?(pattern) click to toggle source
# File lib/semver.rb, line 94
def matched_by?(pattern)
  # For the time being, this is restricted to exact version matches and
  # simple range patterns.  In the future, we should implement some or all of
  # the comparison operators here:
  # https://github.com/isaacs/node-semver/blob/d474801/semver.js#L340

  case pattern
  when SIMPLE_RANGE
    pattern = SIMPLE_RANGE.match(pattern).captures
    pattern[1] = @minor unless pattern[1] && pattern[1] !~ /x/
    pattern[2] = @tiny  unless pattern[2] && pattern[2] !~ /x/
    [@major, @minor, @tiny] == pattern.map { |x| x.to_i }
  when VERSION
    self == SemVer.new(pattern)
  else
    false
  end
end
to_s()
Alias for: inspect