Class: SemVer
Overview
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
Constant Summary collapse
- VERSION =
/^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z-]*|)$/
- SIMPLE_RANGE =
/^v?(\d+|[xX])(?:\.(\d+|[xX])(?:\.(\d+|[xX]))?)?$/
- MIN =
SemVer.new('0.0.0-')
- MAX =
SemVer.new('8.0.0')
Instance Attribute Summary collapse
-
#major ⇒ Object
readonly
Returns the value of attribute major.
-
#minor ⇒ Object
readonly
Returns the value of attribute minor.
-
#special ⇒ Object
readonly
Returns the value of attribute special.
-
#tiny ⇒ Object
readonly
Returns the value of attribute tiny.
Class Method Summary collapse
- .[](range) ⇒ Object
- .find_matching(pattern, versions) ⇒ Object
- .pre(vstring) ⇒ Object
- .valid?(ver) ⇒ Boolean
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#initialize(ver) ⇒ SemVer
constructor
A new instance of SemVer.
- #inspect ⇒ Object (also: #to_s)
- #matched_by?(pattern) ⇒ Boolean
Constructor Details
#initialize(ver) ⇒ SemVer
Returns a new instance of SemVer.
69 70 71 72 73 74 75 76 77 78 79 |
# 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 |
Instance Attribute Details
#major ⇒ Object (readonly)
Returns the value of attribute major.
67 68 69 |
# File 'lib/semver.rb', line 67 def major @major end |
#minor ⇒ Object (readonly)
Returns the value of attribute minor.
67 68 69 |
# File 'lib/semver.rb', line 67 def minor @minor end |
#special ⇒ Object (readonly)
Returns the value of attribute special.
67 68 69 |
# File 'lib/semver.rb', line 67 def special @special end |
#tiny ⇒ Object (readonly)
Returns the value of attribute tiny.
67 68 69 |
# File 'lib/semver.rb', line 67 def tiny @tiny end |
Class Method Details
.[](range) ⇒ Object
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 |
# 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/i, '0')) SemVer.new(r.gsub(/x/i, '0'))...SemVer.new(r.gsub(/(\d+)\.x/i) { "#{$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) ⇒ Object
16 17 18 |
# File 'lib/semver.rb', line 16 def self.find_matching(pattern, versions) versions.select { |v| v.matched_by?("#{pattern}") }.sort.last end |
.pre(vstring) ⇒ Object
20 21 22 |
# File 'lib/semver.rb', line 20 def self.pre(vstring) vstring =~ /-/ ? vstring : vstring + '-' end |
.valid?(ver) ⇒ Boolean
12 13 14 |
# File 'lib/semver.rb', line 12 def self.valid?(ver) VERSION =~ ver end |
Instance Method Details
#<=>(other) ⇒ Object
81 82 83 84 85 86 87 88 89 90 91 92 |
# 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 ⇒ Object Also known as: to_s
113 114 115 |
# File 'lib/semver.rb', line 113 def inspect @vstring || "v#{@major}.#{@minor}.#{@tiny}#{@special}" end |
#matched_by?(pattern) ⇒ Boolean
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# 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/i pattern[2] = @tiny unless pattern[2] && pattern[2] !~ /x/i [@major, @minor, @tiny] == pattern.map { |x| x.to_i } when VERSION self == SemVer.new(pattern) else false end end |