class SemVersion
Constants
- PRE_METADATA_REGEX
- SEMVER_REGEX
Pattern allows min and patch to be skipped. We have to do extra checking if we want them
- VERSION
Attributes
major[R]
metadata[R]
minor[R]
patch[R]
pre[R]
prerelease[R]
Public Class Methods
from_loose_version(string)
click to toggle source
# File lib/sem_version.rb, line 41 def self.from_loose_version(string) match = string.match(SEMVER_REGEX) raise ArgumentError, "Version string #{string} is not valid" unless match maj, min, pat, pre, bui = match.captures min = 0 if min.nil? || min.empty? pat = 0 if pat.nil? || pat.empty? new(maj.to_i, min.to_i, pat.to_i, pre, bui) end
new(*args)
click to toggle source
Format were raw bits are passed in is undocumented, and not validity checked
# File lib/sem_version.rb, line 14 def initialize(*args) if args.first.is_a?(String) @major, @minor, @patch, @pre, @metadata = self.class.parse(args.first) # Validation should be handled at a string level by self.parse, but validate anyway validate elsif args.first.is_a?(Hash) @major, @minor, @patch, @pre, @metadata = args.first.values_at(:major, :minor, :patch, :pre, :metadata) # Allow :prerelease as well @pre ||= args.first[:prerelease] validate elsif args.first.is_a?(Array) @major, @minor, @patch, @pre, @metadata = *args.first validate else @major, @minor, @patch, @pre, @metadata = *args validate end end
open_constraint?(constraint)
click to toggle source
# File lib/sem_version.rb, line 94 def self.open_constraint?(constraint) comparison, _ = self.split_constraint(constraint) comparison != '=' end
parse(string)
click to toggle source
# File lib/sem_version.rb, line 33 def self.parse(string) match = string.match(SEMVER_REGEX) raise ArgumentError, "Version string #{string} is not valid" unless match maj, min, pat, pre, bui = match.captures raise ArgumentError, "Version string #{string} is not valid" if min.empty? || pat.empty? [maj.to_i, min.to_i, pat.to_i, pre, bui] end
split_constraint(constraint)
click to toggle source
# File lib/sem_version.rb, line 99 def self.split_constraint(constraint) comparison, version = constraint.strip.split(' ', 2) comparison, version = '=', comparison if version.nil? comparison = '=' if comparison == '==' [comparison, version] end
valid?(string)
click to toggle source
# File lib/sem_version.rb, line 50 def self.valid?(string) matches = string.match(SEMVER_REGEX) matches && !matches[2].nil? && !matches[3].nil? end
Public Instance Methods
<=>(other)
click to toggle source
# File lib/sem_version.rb, line 55 def <=>(other) maj = @major <=> other.major return maj unless maj == 0 min = @minor <=> other.minor return min unless min == 0 pat = @patch <=> other.patch return pat unless pat == 0 pre = compare_sep(@pre, other.pre, true) return pre unless pre == 0 return 0 end
inspect()
click to toggle source
# File lib/sem_version.rb, line 152 def inspect "#<SemVersion: #{to_s}>" end
major=(val)
click to toggle source
# File lib/sem_version.rb, line 106 def major=(val) raise ArgumentError, "#{val} is not a valid major version (must be an integer >= 0)" unless val.is_a?(Integer) && val >= 0 @major = val end
metadata=(val)
click to toggle source
# File lib/sem_version.rb, line 129 def metadata=(val) unless val.nil? || (val.is_a?(String) && val =~ PRE_METADATA_REGEX) raise ArgumentError, "#{val} is not a valid metadata string (must be nil, or a string following http://semver.org constraints)" end @metadata = val end
minor=(val)
click to toggle source
# File lib/sem_version.rb, line 111 def minor=(val) raise ArgumentError, "#{val} is not a valid minor version (must be an integer >= 0)" unless val.is_a?(Integer) && val >= 0 @minor = val end
patch=(val)
click to toggle source
# File lib/sem_version.rb, line 116 def patch=(val) raise ArgumentError, "#{val} is not a valid patch version (must be an integer >= 0)" unless val.is_a?(Integer) && val >= 0 @patch = val end
pre=(val)
click to toggle source
# File lib/sem_version.rb, line 121 def pre=(val) unless val.nil? || (val.is_a?(String) && val =~ PRE_METADATA_REGEX) raise ArgumentError, "#{val} is not a valid pre-release version (must be nil, or a string following http://semver.org constraints)" end @pre = val end
Also aliased as: prerelease=
satisfies?(constraint)
click to toggle source
# File lib/sem_version.rb, line 71 def satisfies?(constraint) comparison, version = self.class.split_constraint(constraint) # Allow pessimistic operator if comparison == '~>' match = version.match(/^(\d+)\.(\d+)\.?(\d*)$/) raise ArgumentError, "Pessimistic constraints must have a version in the form 'x.y' or 'x.y.z'" unless match maj, min, pat = match.captures if pat.empty? lower = "#{maj}.#{min}.0" upper = "#{maj.to_i+1}.0.0" else lower = "#{maj}.#{min}.#{pat}" upper = "#{maj}.#{min.to_i+1}.0" end send('>=', SemVersion.new(lower)) && send('<', SemVersion.new(upper)) else comparison = '==' if comparison == '=' semversion = self.class.from_loose_version(version) send(comparison, semversion) end end
to_a()
click to toggle source
# File lib/sem_version.rb, line 143 def to_a [@major, @minor, @patch, @pre, @metadata] end
to_h()
click to toggle source
# File lib/sem_version.rb, line 147 def to_h h = [:major, :minor, :patch, :pre, :metadata].zip(to_a) Hash[h.reject{ |k,v| v.nil? }] end
to_s()
click to toggle source
# File lib/sem_version.rb, line 136 def to_s r = "#{@major}.#{@minor}.#{@patch}" r << "-#{@pre}" if @pre r << "+#{@metadata}" if @metadata r end
Private Instance Methods
compare_sep(ours, theirs, nil_wins)
click to toggle source
# File lib/sem_version.rb, line 158 def compare_sep(ours, theirs, nil_wins) # Both nil? They're equal return 0 if ours.nil? && theirs.nil? # One's nil? The winner is determined by precidence return nil_wins ? -1 : 1 if theirs.nil? return nil_wins ? 1 : -1 if ours.nil? our_parts = ours.split('.') their_parts = theirs.split('.') our_parts.zip(their_parts) do |a,b| # b can be nil, in which case it loses return 1 if b.nil? # If they're both ints, convert to as such # If one's an int and the other isn't, the string version of the int gets correctly compared a, b = a.to_i, b.to_i if a =~ /^\d+$/ && b =~ /^\d+$/ comp = a <=> b return comp unless comp == 0 end # If we got this far, either they're equal (same length) or they won return (our_parts.length == their_parts.length) ? 0 : -1 end
validate()
click to toggle source
# File lib/sem_version.rb, line 183 def validate # Validates the instance variables. Different approach to validating a raw string raise ArgumentError, "Invalid version (major is not an int >= 0)" unless @major.is_a?(Integer) && @major >= 0 raise ArgumentError, "Invalid version (minor is not an int >= 0)" unless @minor.is_a?(Integer) && @minor >= 0 raise ArgumentError, "Invalid version (patch is not an int >= 0)" unless @patch.is_a?(Integer) && @patch >= 0 unless @pre.nil? || (@pre.is_a?(String) && @pre =~ PRE_METADATA_REGEX) raise ArgumentError, "Invalid version (pre must be nil, or a string following http://semver.org contraints)" end unless @metadata.nil? || (@metadata.is_a?(String) && @metadata =~ PRE_METADATA_REGEX) raise ArgumentError, "Invalid version (metadata must be nil, or a string following http://semver.org contraints)" end end