Class: Semverse::Constraint
- Inherits:
-
Object
- Object
- Semverse::Constraint
- Defined in:
- lib/semverse/constraint.rb
Constant Summary collapse
- DEFAULT_OPERATOR =
The default constraint string.
'='.freeze
- OPERATORS =
The complete list of possible operators, paired with a proc to be used for evaluation.
{ #:nodoc: '=' => ->(c, v) { v == c.version }, '!=' => ->(c, v) { v != c.version }, '>' => ->(c, v) { v > c.version }, '<' => ->(c, v) { v < c.version }, '>=' => ->(c, v) { v >= c.version }, '<=' => ->(c, v) { v <= c.version }, '~' => method(:compare_approx), '~>' => method(:compare_approx), }.freeze
- REGEX =
This is a magical regular expression that matches the Semantic versioning specification found at semver.org. In addition to supporting all the possible versions, it also provides a named
match_data
which makes it really delightful to work with. /\A ((?<operator>(#{OPERATORS.keys.join('|')}))[[:space:]]*)? (?<major>\d+) (\.(?<minor>\d+))? (\.(?<patch>\d+))? (\-(?<pre_release>[0-9A-Za-z\-\.]+))? (\+(?<build>[0-9A-Za-z\-\.]+))? \z/x.freeze
Instance Attribute Summary collapse
-
#build ⇒ Object
readonly
Returns the value of attribute build.
-
#major ⇒ Object
readonly
Returns the value of attribute major.
-
#minor ⇒ Object
readonly
Returns the value of attribute minor.
-
#operator ⇒ Object
readonly
Returns the value of attribute operator.
-
#patch ⇒ Object
readonly
Returns the value of attribute patch.
-
#pre_release ⇒ Object
readonly
Returns the value of attribute pre_release.
-
#version ⇒ Semverse::Version
readonly
Return the Semverse::Version representation of the major, minor, and patch attributes of this instance.
Class Method Summary collapse
-
.coerce(object) ⇒ Constraint
Coerce the object into a constraint.
- .compare_approx(constraint, target_version) ⇒ Boolean
-
.satisfy_all(constraints, versions) ⇒ Array<Semverse::Version>
Returns all of the versions which satisfy all of the given constraints.
-
.satisfy_best(constraints, versions) ⇒ Semverse::Version
Return the best version from the given list of versions for the given list of constraints.
-
.split(constraint) ⇒ Array?
Split a constraint string into an Array of two elements.
Instance Method Summary collapse
- #==(other) ⇒ Boolean (also: #eql?)
-
#initialize(constraint = '>= 0.0.0') ⇒ Constraint
constructor
A new instance of Constraint.
-
#inspect ⇒ String
The detailed string representation of this constraint.
-
#satisfies?(target) ⇒ Boolean
(also: #include?)
Returns true or false if the given version would be satisfied by the version constraint.
-
#to_s ⇒ String
The string representation of this constraint.
Constructor Details
#initialize(constraint = '>= 0.0.0') ⇒ Constraint
Returns a new instance of Constraint.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/semverse/constraint.rb', line 168 def initialize(constraint = '>= 0.0.0') constraint = constraint.to_s if constraint.nil? || constraint.empty? constraint = ">= 0.0.0" end @operator, @major, @minor, @patch, @pre_release, @build = self.class.split(constraint) unless ['~>', '~'].include?(@operator) @minor ||= 0 @patch ||= 0 end @version = Version.new([ self.major, self.minor, self.patch, self.pre_release, self.build, ]) end |
Instance Attribute Details
#build ⇒ Object (readonly)
Returns the value of attribute build.
159 160 161 |
# File 'lib/semverse/constraint.rb', line 159 def build @build end |
#major ⇒ Object (readonly)
Returns the value of attribute major.
155 156 157 |
# File 'lib/semverse/constraint.rb', line 155 def major @major end |
#minor ⇒ Object (readonly)
Returns the value of attribute minor.
156 157 158 |
# File 'lib/semverse/constraint.rb', line 156 def minor @minor end |
#operator ⇒ Object (readonly)
Returns the value of attribute operator.
154 155 156 |
# File 'lib/semverse/constraint.rb', line 154 def operator @operator end |
#patch ⇒ Object (readonly)
Returns the value of attribute patch.
157 158 159 |
# File 'lib/semverse/constraint.rb', line 157 def patch @patch end |
#pre_release ⇒ Object (readonly)
Returns the value of attribute pre_release.
158 159 160 |
# File 'lib/semverse/constraint.rb', line 158 def pre_release @pre_release end |
#version ⇒ Semverse::Version (readonly)
Return the Semverse::Version representation of the major, minor, and patch attributes of this instance
165 166 167 |
# File 'lib/semverse/constraint.rb', line 165 def version @version end |
Class Method Details
.coerce(object) ⇒ Constraint
Coerce the object into a constraint.
9 10 11 12 13 14 15 |
# File 'lib/semverse/constraint.rb', line 9 def coerce(object) if object.nil? DEFAULT_CONSTRAINT else object.is_a?(self) ? object : new(object) end end |
.compare_approx(constraint, target_version) ⇒ Boolean
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/semverse/constraint.rb', line 97 def compare_approx(constraint, target_version) min = constraint.version max = if constraint.patch.nil? Version.new([min.major + 1, 0, 0, 0]) elsif constraint.build identifiers = constraint.version.identifiers(:build) replace = identifiers.last.to_i.to_s == identifiers.last.to_s ? "-" : nil Version.new([min.major, min.minor, min.patch, min.pre_release, identifiers.fill(replace, -1).join('.')]) elsif constraint.pre_release identifiers = constraint.version.identifiers(:pre_release) replace = identifiers.last.to_i.to_s == identifiers.last.to_s ? "-" : nil Version.new([min.major, min.minor, min.patch, identifiers.fill(replace, -1).join('.')]) else Version.new([min.major, min.minor + 1, 0, 0]) end min <= target_version && target_version < max end |
.satisfy_all(constraints, versions) ⇒ Array<Semverse::Version>
Returns all of the versions which satisfy all of the given constraints
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/semverse/constraint.rb', line 23 def satisfy_all(constraints, versions) constraints = Array(constraints).collect do |con| con.is_a?(Constraint) ? con : Constraint.new(con) end.uniq versions = Array(versions).collect do |ver| ver.is_a?(Version) ? ver : Version.new(ver) end.uniq versions.select do |ver| constraints.all? { |constraint| constraint.satisfies?(ver) } end end |
.satisfy_best(constraints, versions) ⇒ Semverse::Version
Return the best version from the given list of versions for the given list of constraints
45 46 47 48 49 50 51 52 53 |
# File 'lib/semverse/constraint.rb', line 45 def satisfy_best(constraints, versions) solution = satisfy_all(constraints, versions) if solution.empty? raise NoSolutionError end solution.sort.last end |
.split(constraint) ⇒ Array?
Split a constraint string into an Array of two elements. The first element being the operator and second being the version string.
If the given string does not contain a constraint operator then (=) will be used.
If the given string does not contain a valid version string then nil will be returned.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/semverse/constraint.rb', line 76 def split(constraint) data = REGEX.match(constraint) if data.nil? raise InvalidConstraintFormat.new(constraint) else [ data[:operator] || DEFAULT_OPERATOR, data[:major].to_i, data[:minor] && data[:minor].to_i, data[:patch] && data[:patch].to_i, data[:pre_release], data[:build], ] end end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
212 213 214 215 216 |
# File 'lib/semverse/constraint.rb', line 212 def ==(other) other.is_a?(self.class) && self.operator == other.operator && self.version == other.version end |
#inspect ⇒ String
The detailed string representation of this constraint.
222 223 224 |
# File 'lib/semverse/constraint.rb', line 222 def inspect "#<#{self.class.to_s} #{to_s}>" end |
#satisfies?(target) ⇒ Boolean Also known as: include?
Returns true or false if the given version would be satisfied by the version constraint.
195 196 197 198 199 200 201 202 203 |
# File 'lib/semverse/constraint.rb', line 195 def satisfies?(target) target = Version.coerce(target) if !version.zero? && greedy_match?(target) return false end OPERATORS[operator].call(self, target) end |
#to_s ⇒ String
The string representation of this constraint.
229 230 231 232 233 234 235 236 |
# File 'lib/semverse/constraint.rb', line 229 def to_s out = "#{operator} #{major}" out << ".#{minor}" if minor out << ".#{patch}" if patch out << "-#{pre_release}" if pre_release out << "+#{build}" if build out end |