Class: SemVersion
Constant Summary collapse
- VERSION =
'2.0.1'- SEMVER_REGEX =
Pattern allows min and patch to be skipped. We have to do extra checking if we want them
/^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?)?)?$/- PRE_METADATA_REGEX =
/^[\dA-Za-z\-]+(\.[\dA-Za-z\-]+)*$/
Instance Attribute Summary collapse
-
#major ⇒ Object
Returns the value of attribute major.
-
#metadata ⇒ Object
Returns the value of attribute metadata.
-
#minor ⇒ Object
Returns the value of attribute minor.
-
#patch ⇒ Object
Returns the value of attribute patch.
-
#pre ⇒ Object
(also: #prerelease)
Returns the value of attribute pre.
Class Method Summary collapse
- .from_loose_version(string) ⇒ Object
- .open_constraint?(constraint) ⇒ Boolean
- .parse(string) ⇒ Object
- .split_constraint(constraint) ⇒ Object
- .valid?(string) ⇒ Boolean
Instance Method Summary collapse
- #<=>(other) ⇒ Object
-
#initialize(*args) ⇒ SemVersion
constructor
Format were raw bits are passed in is undocumented, and not validity checked.
- #inspect ⇒ Object
- #satisfies?(constraint) ⇒ Boolean
- #to_a ⇒ Object
- #to_h ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(*args) ⇒ SemVersion
Format were raw bits are passed in is undocumented, and not validity checked
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/sem_version.rb', line 14 def initialize(*args) if args.first.is_a?(String) @major, @minor, @patch, @pre, = 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, = 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, = *args.first validate else @major, @minor, @patch, @pre, = *args validate end end |
Instance Attribute Details
#major ⇒ Object
Returns the value of attribute major.
10 11 12 |
# File 'lib/sem_version.rb', line 10 def major @major end |
#metadata ⇒ Object
Returns the value of attribute metadata.
10 11 12 |
# File 'lib/sem_version.rb', line 10 def end |
#minor ⇒ Object
Returns the value of attribute minor.
10 11 12 |
# File 'lib/sem_version.rb', line 10 def minor @minor end |
#patch ⇒ Object
Returns the value of attribute patch.
10 11 12 |
# File 'lib/sem_version.rb', line 10 def patch @patch end |
#pre ⇒ Object Also known as: prerelease
Returns the value of attribute pre.
10 11 12 |
# File 'lib/sem_version.rb', line 10 def pre @pre end |
Class Method Details
.from_loose_version(string) ⇒ Object
41 42 43 44 45 46 47 48 |
# 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 |
.open_constraint?(constraint) ⇒ Boolean
94 95 96 97 |
# File 'lib/sem_version.rb', line 94 def self.open_constraint?(constraint) comparison, _ = self.split_constraint(constraint) comparison != '=' end |
.parse(string) ⇒ Object
33 34 35 36 37 38 39 |
# 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) ⇒ Object
99 100 101 102 103 104 |
# 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) ⇒ Boolean
50 51 52 53 |
# File 'lib/sem_version.rb', line 50 def self.valid?(string) matches = string.match(SEMVER_REGEX) matches && !matches[2].nil? && !matches[3].nil? end |
Instance Method Details
#<=>(other) ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# 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 ⇒ Object
152 153 154 |
# File 'lib/sem_version.rb', line 152 def inspect "#<SemVersion: #{to_s}>" end |
#satisfies?(constraint) ⇒ Boolean
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# 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 ⇒ Object
143 144 145 |
# File 'lib/sem_version.rb', line 143 def to_a [@major, @minor, @patch, @pre, ] end |
#to_h ⇒ Object
147 148 149 150 |
# 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 ⇒ Object
136 137 138 139 140 141 |
# File 'lib/sem_version.rb', line 136 def to_s r = "#{@major}.#{@minor}.#{@patch}" r << "-#{@pre}" if @pre r << "+#{@metadata}" if r end |