vers 1.3.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +29 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +27 -24
- data/lib/vers/bazel_version.rb +114 -0
- data/lib/vers/composer_version.rb +117 -0
- data/lib/vers/conan_version.rb +87 -0
- data/lib/vers/constraint.rb +7 -3
- data/lib/vers/distribution_version.rb +482 -0
- data/lib/vers/gem_version.rb +81 -0
- data/lib/vers/interval.rb +49 -33
- data/lib/vers/maven_version.rb +16 -0
- data/lib/vers/nuget_version.rb +14 -0
- data/lib/vers/parser.rb +893 -202
- data/lib/vers/pub_version.rb +59 -0
- data/lib/vers/pypi_version.rb +256 -0
- data/lib/vers/scheme.rb +52 -0
- data/lib/vers/semver_version.rb +294 -0
- data/lib/vers/special_version.rb +336 -0
- data/lib/vers/version.rb +68 -13
- data/lib/vers/version_comparison.rb +26 -0
- data/lib/vers/version_range.rb +201 -48
- data/lib/vers.rb +39 -9
- metadata +15 -4
data/lib/vers/version_range.rb
CHANGED
|
@@ -5,17 +5,26 @@ require_relative 'version'
|
|
|
5
5
|
|
|
6
6
|
module Vers
|
|
7
7
|
class VersionRange
|
|
8
|
-
|
|
8
|
+
VALIDATED_CONTAINMENT_SCHEMES = %w[bazel cargo composer go hex npm pub pypi semver].freeze
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
attr_reader :intervals, :raw_constraints, :scheme, :exclusions
|
|
11
|
+
|
|
12
|
+
def initialize(intervals = [], raw_constraints: nil, scheme: nil, exclusions: [])
|
|
13
|
+
canonical_scheme = Scheme.canonical(scheme)
|
|
14
|
+
interval_schemes = intervals.compact.map(&:scheme).compact.map { |value| Scheme.canonical(value) }.uniq
|
|
15
|
+
if interval_schemes.length > 1 || (canonical_scheme && interval_schemes.any? { |value| value != canonical_scheme })
|
|
16
|
+
raise ArgumentError, "Cannot combine different version range schemes"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
@scheme = canonical_scheme || interval_schemes.first
|
|
20
|
+
@intervals = intervals.select { |interval| interval && !interval.empty? }.map { |interval| interval.with_scheme(@scheme) }
|
|
13
21
|
if @scheme
|
|
14
22
|
@intervals.sort! { |a, b| compare_interval_bounds(a, b) }
|
|
15
23
|
else
|
|
16
24
|
@intervals.sort_by! { |i| [i.min || '', i.max || ''] }
|
|
17
25
|
end
|
|
18
26
|
@raw_constraints = raw_constraints
|
|
27
|
+
@exclusions = exclusions.dup
|
|
19
28
|
merge_overlapping_intervals!
|
|
20
29
|
end
|
|
21
30
|
|
|
@@ -44,35 +53,206 @@ module Vers
|
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
def unbounded?
|
|
47
|
-
intervals.length == 1 && intervals.first.unbounded?
|
|
56
|
+
exclusions.empty? && intervals.length == 1 && intervals.first.unbounded?
|
|
48
57
|
end
|
|
49
58
|
|
|
50
59
|
def contains?(version)
|
|
51
|
-
|
|
60
|
+
if VALIDATED_CONTAINMENT_SCHEMES.include?(scheme) && !Version.valid?(version, scheme)
|
|
61
|
+
return false
|
|
62
|
+
end
|
|
63
|
+
return false if exclusions.any? { |excluded| excluded_version?(version, excluded) }
|
|
64
|
+
|
|
65
|
+
intervals.any? do |interval|
|
|
66
|
+
contains = if scheme == "composer"
|
|
67
|
+
composer_interval_contains?(interval, version)
|
|
68
|
+
elsif scheme == "pypi"
|
|
69
|
+
pypi_interval_contains?(interval, version)
|
|
70
|
+
else
|
|
71
|
+
interval.contains?(version)
|
|
72
|
+
end
|
|
73
|
+
contains && prerelease_allowed?(interval, version)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def composer_interval_contains?(interval, version)
|
|
78
|
+
candidate_branch = ComposerVersion.branch?(version)
|
|
79
|
+
minimum_branch = interval.min && ComposerVersion.branch?(interval.min)
|
|
80
|
+
maximum_branch = interval.max && ComposerVersion.branch?(interval.max)
|
|
81
|
+
return interval.contains?(version) unless candidate_branch || minimum_branch || maximum_branch
|
|
82
|
+
return true if interval.unbounded?
|
|
83
|
+
|
|
84
|
+
candidate_branch && minimum_branch && maximum_branch &&
|
|
85
|
+
interval.min_inclusive && interval.max_inclusive && interval.min == interval.max && version == interval.min
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def pypi_interval_contains?(interval, version)
|
|
89
|
+
if interval.min && interval.max && interval.min_inclusive && interval.max_inclusive &&
|
|
90
|
+
PyPIVersion.compare(interval.min, interval.max).zero?
|
|
91
|
+
return PyPIVersion.specifier_equal?(version, interval.min)
|
|
92
|
+
end
|
|
93
|
+
return false unless interval.contains?(version)
|
|
94
|
+
|
|
95
|
+
candidate = PyPIVersion.parse(version)
|
|
96
|
+
return false unless candidate
|
|
97
|
+
|
|
98
|
+
if interval.min && !interval.min_inclusive
|
|
99
|
+
bound = PyPIVersion.parse(interval.min)
|
|
100
|
+
if bound
|
|
101
|
+
return false if PyPIVersion.specifier_equal?(version, interval.min)
|
|
102
|
+
|
|
103
|
+
without_post = PyPIVersion.without_post_and_dev(candidate)
|
|
104
|
+
if candidate.post_number && PyPIVersion.versions_equal?(without_post, bound, ignore_local: true)
|
|
105
|
+
return false
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
if interval.max && !interval.max_inclusive
|
|
111
|
+
bound = PyPIVersion.parse(interval.max)
|
|
112
|
+
if bound
|
|
113
|
+
bound_is_release = bound.pre_tag.nil? && bound.post_number.nil? && bound.dev_number.nil?
|
|
114
|
+
if bound_is_release && PyPIVersion.same_release?(candidate, bound) &&
|
|
115
|
+
(!candidate.pre_tag.nil? || !candidate.dev_number.nil?)
|
|
116
|
+
return false
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
without_dev = PyPIVersion.without_dev(candidate)
|
|
120
|
+
if candidate.dev_number && PyPIVersion.versions_equal?(without_dev, bound, ignore_local: true)
|
|
121
|
+
return false
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
true
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def prerelease_allowed?(interval, version)
|
|
130
|
+
return true unless %w[npm cargo].include?(scheme)
|
|
131
|
+
|
|
132
|
+
candidate = SemverVersion.parse(version.to_s.strip)
|
|
133
|
+
return false unless candidate
|
|
134
|
+
return true if candidate.prerelease.empty?
|
|
135
|
+
|
|
136
|
+
[interval.min, interval.max].compact.any? do |bound|
|
|
137
|
+
parsed_bound = SemverVersion.parse(bound.to_s.strip)
|
|
138
|
+
next false unless parsed_bound && !parsed_bound.prerelease.empty?
|
|
139
|
+
|
|
140
|
+
candidate.core.zip(parsed_bound.core).all? do |candidate_part, bound_part|
|
|
141
|
+
VersionComparison.compare_numbers(candidate_part, bound_part).zero?
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def excluded_version?(version, excluded)
|
|
147
|
+
if scheme == "pypi"
|
|
148
|
+
PyPIVersion.specifier_equal?(version, excluded)
|
|
149
|
+
elsif scheme == "composer" && (ComposerVersion.branch?(version) || ComposerVersion.branch?(excluded))
|
|
150
|
+
version == excluded
|
|
151
|
+
else
|
|
152
|
+
Version.compare_with_scheme(version, excluded, scheme).zero?
|
|
153
|
+
end
|
|
52
154
|
end
|
|
53
155
|
|
|
54
156
|
def intersect(other)
|
|
55
|
-
merged_scheme =
|
|
157
|
+
merged_scheme = compatible_scheme(other)
|
|
56
158
|
result_intervals = []
|
|
57
159
|
|
|
58
160
|
intervals.each do |interval1|
|
|
59
161
|
other.intervals.each do |interval2|
|
|
60
|
-
intersection = interval1
|
|
162
|
+
intersection = intersect_intervals(interval1, interval2, merged_scheme)
|
|
61
163
|
result_intervals << intersection unless intersection.empty?
|
|
62
164
|
end
|
|
63
165
|
end
|
|
64
166
|
|
|
65
167
|
combined_raw = (raw_constraints || intervals) + (other.raw_constraints || other.intervals)
|
|
66
|
-
self.class.new(
|
|
168
|
+
self.class.new(
|
|
169
|
+
result_intervals,
|
|
170
|
+
raw_constraints: combined_raw,
|
|
171
|
+
scheme: merged_scheme,
|
|
172
|
+
exclusions: exclusions + other.exclusions
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def intersect_intervals(left, right, comparison_scheme)
|
|
177
|
+
return left.intersect(right) unless comparison_scheme == "pypi"
|
|
178
|
+
|
|
179
|
+
left = left.with_scheme(comparison_scheme)
|
|
180
|
+
right = right.with_scheme(comparison_scheme)
|
|
181
|
+
left_exact = exact_interval?(left)
|
|
182
|
+
right_exact = exact_interval?(right)
|
|
183
|
+
return left.intersect(right) unless left_exact || right_exact
|
|
184
|
+
|
|
185
|
+
if left_exact && right_exact
|
|
186
|
+
left_contains_right = pypi_interval_contains?(left, right.min)
|
|
187
|
+
right_contains_left = pypi_interval_contains?(right, left.min)
|
|
188
|
+
return right if left_contains_right && !right_contains_left
|
|
189
|
+
return left if right_contains_left
|
|
190
|
+
return left if left_contains_right
|
|
191
|
+
|
|
192
|
+
return Interval.empty(scheme: comparison_scheme)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
exact = left_exact ? left : right
|
|
196
|
+
other_interval = left_exact ? right : left
|
|
197
|
+
return exact if pypi_interval_contains?(other_interval, exact.min)
|
|
198
|
+
|
|
199
|
+
Interval.empty(scheme: comparison_scheme)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def exact_interval?(interval)
|
|
203
|
+
interval.min && interval.max && interval.min_inclusive && interval.max_inclusive &&
|
|
204
|
+
Version.compare_for_range(interval.min, interval.max, interval.scheme || scheme).zero?
|
|
67
205
|
end
|
|
68
206
|
|
|
69
207
|
def union(other)
|
|
70
|
-
merged_scheme =
|
|
208
|
+
merged_scheme = compatible_scheme(other)
|
|
71
209
|
combined_raw = (raw_constraints || intervals) + (other.raw_constraints || other.intervals)
|
|
72
|
-
|
|
210
|
+
left = with_scheme(merged_scheme)
|
|
211
|
+
right = other.with_scheme(merged_scheme)
|
|
212
|
+
combined_exclusions = []
|
|
213
|
+
left.exclusions.each do |excluded|
|
|
214
|
+
combined_exclusions << excluded unless right.contains?(excluded)
|
|
215
|
+
end
|
|
216
|
+
right.exclusions.each do |excluded|
|
|
217
|
+
next if left.contains?(excluded) || combined_exclusions.include?(excluded)
|
|
218
|
+
|
|
219
|
+
combined_exclusions << excluded
|
|
220
|
+
end
|
|
221
|
+
self.class.new(
|
|
222
|
+
intervals + other.intervals,
|
|
223
|
+
raw_constraints: combined_raw,
|
|
224
|
+
scheme: merged_scheme,
|
|
225
|
+
exclusions: combined_exclusions
|
|
226
|
+
)
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
def with_scheme(value)
|
|
230
|
+
canonical = Scheme.canonical(value)
|
|
231
|
+
if scheme && canonical && scheme != canonical
|
|
232
|
+
raise ArgumentError, "Cannot combine #{scheme} and #{canonical} version ranges"
|
|
233
|
+
end
|
|
234
|
+
return self if scheme == canonical
|
|
235
|
+
|
|
236
|
+
self.class.new(intervals, raw_constraints: raw_constraints, scheme: canonical, exclusions: exclusions)
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def compatible_scheme(other)
|
|
240
|
+
if scheme && other.scheme && scheme != other.scheme
|
|
241
|
+
raise ArgumentError, "Cannot combine #{scheme} and #{other.scheme} version ranges"
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
scheme || other.scheme
|
|
73
245
|
end
|
|
74
246
|
|
|
75
247
|
def complement
|
|
248
|
+
unless exclusions.empty?
|
|
249
|
+
base = self.class.new(intervals, scheme: scheme).complement
|
|
250
|
+
exclusions.each do |excluded|
|
|
251
|
+
base = base.union(self.class.exact(excluded, scheme: scheme))
|
|
252
|
+
end
|
|
253
|
+
return base
|
|
254
|
+
end
|
|
255
|
+
|
|
76
256
|
return self.class.unbounded(scheme: @scheme) if empty?
|
|
77
257
|
return self.class.empty(scheme: @scheme) if unbounded?
|
|
78
258
|
|
|
@@ -121,37 +301,14 @@ module Vers
|
|
|
121
301
|
end
|
|
122
302
|
|
|
123
303
|
def exclude(version)
|
|
124
|
-
return self
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
min: interval.min,
|
|
133
|
-
max: version,
|
|
134
|
-
min_inclusive: interval.min_inclusive,
|
|
135
|
-
max_inclusive: false,
|
|
136
|
-
scheme: @scheme
|
|
137
|
-
)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
if interval.max.nil? || version_compare(version, interval.max) < 0
|
|
141
|
-
result_intervals << Interval.new(
|
|
142
|
-
min: version,
|
|
143
|
-
max: interval.max,
|
|
144
|
-
min_inclusive: false,
|
|
145
|
-
max_inclusive: interval.max_inclusive,
|
|
146
|
-
scheme: @scheme
|
|
147
|
-
)
|
|
148
|
-
end
|
|
149
|
-
else
|
|
150
|
-
result_intervals << interval
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
self.class.new(result_intervals, raw_constraints: raw_constraints, scheme: @scheme)
|
|
304
|
+
return self unless contains?(version)
|
|
305
|
+
|
|
306
|
+
self.class.new(
|
|
307
|
+
intervals,
|
|
308
|
+
raw_constraints: raw_constraints,
|
|
309
|
+
scheme: scheme,
|
|
310
|
+
exclusions: exclusions + [version]
|
|
311
|
+
)
|
|
155
312
|
end
|
|
156
313
|
|
|
157
314
|
def to_s
|
|
@@ -186,11 +343,7 @@ module Vers
|
|
|
186
343
|
return -1 if a.nil?
|
|
187
344
|
return 1 if b.nil?
|
|
188
345
|
|
|
189
|
-
|
|
190
|
-
Version.compare_with_scheme(a, b, @scheme)
|
|
191
|
-
else
|
|
192
|
-
Version.compare(a, b)
|
|
193
|
-
end
|
|
346
|
+
Version.compare_for_range(a, b, @scheme)
|
|
194
347
|
end
|
|
195
348
|
|
|
196
349
|
def compare_interval_bounds(a, b)
|
|
@@ -220,4 +373,4 @@ module Vers
|
|
|
220
373
|
end
|
|
221
374
|
end
|
|
222
375
|
end
|
|
223
|
-
end
|
|
376
|
+
end
|
data/lib/vers.rb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "vers/version"
|
|
4
4
|
require_relative "vers/maven_version"
|
|
5
5
|
require_relative "vers/nuget_version"
|
|
6
|
+
require_relative "vers/bazel_version"
|
|
6
7
|
require_relative "vers/interval"
|
|
7
8
|
require_relative "vers/version_range"
|
|
8
9
|
require_relative "vers/constraint"
|
|
@@ -37,7 +38,7 @@ require_relative "vers/parser"
|
|
|
37
38
|
# gem_range = Vers.parse_native("~> 1.0", "gem")
|
|
38
39
|
#
|
|
39
40
|
# # Check version containment
|
|
40
|
-
# Vers.satisfies?("1.5.0", ">=1.0.0,<2.0.0") # => true
|
|
41
|
+
# Vers.satisfies?("1.5.0", ">=1.0.0,<2.0.0", "pypi") # => true
|
|
41
42
|
#
|
|
42
43
|
# # Compare versions
|
|
43
44
|
# Vers.compare("1.2.3", "1.2.4") # => -1
|
|
@@ -70,7 +71,7 @@ module Vers
|
|
|
70
71
|
# == Examples
|
|
71
72
|
#
|
|
72
73
|
# Vers.parse("vers:npm/>=1.2.3|<2.0.0")
|
|
73
|
-
# Vers.
|
|
74
|
+
# Vers.parse_native("~>1.0", "gem")
|
|
74
75
|
# Vers.parse("*") # unbounded range
|
|
75
76
|
#
|
|
76
77
|
def self.parse(vers_string)
|
|
@@ -152,7 +153,7 @@ module Vers
|
|
|
152
153
|
#
|
|
153
154
|
# @param a [String] First version string
|
|
154
155
|
# @param b [String] Second version string
|
|
155
|
-
# @param scheme [String, nil] Package manager scheme
|
|
156
|
+
# @param scheme [String, nil] Package manager scheme or nil for generic comparison
|
|
156
157
|
# @return [Integer] -1 if a < b, 0 if a == b, 1 if a > b
|
|
157
158
|
#
|
|
158
159
|
def self.compare_with_scheme(a, b, scheme)
|
|
@@ -165,22 +166,51 @@ module Vers
|
|
|
165
166
|
# @param version_string [String] The version string to normalize
|
|
166
167
|
# @return [String] The normalized version string
|
|
167
168
|
#
|
|
168
|
-
def self.normalize(version_string)
|
|
169
|
-
Version.normalize(version_string)
|
|
169
|
+
def self.normalize(version_string, scheme = nil)
|
|
170
|
+
Version.normalize(version_string, scheme)
|
|
170
171
|
end
|
|
171
172
|
|
|
172
173
|
##
|
|
173
174
|
# Checks if a version string is valid
|
|
174
175
|
#
|
|
175
176
|
# @param version_string [String] The version string to validate
|
|
177
|
+
# @param scheme [String, nil] Package manager scheme or nil for generic validation
|
|
176
178
|
# @return [Boolean] true if the version is valid
|
|
177
179
|
#
|
|
178
|
-
def self.valid?(version_string)
|
|
179
|
-
Version.valid?(version_string)
|
|
180
|
+
def self.valid?(version_string, scheme = nil)
|
|
181
|
+
Version.valid?(version_string, scheme)
|
|
180
182
|
end
|
|
181
183
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
##
|
|
185
|
+
# Checks if a version is stable using scheme-specific rules
|
|
186
|
+
#
|
|
187
|
+
# @param version_string [String] The version string to classify
|
|
188
|
+
# @param scheme [String, nil] Package manager scheme or nil for generic classification
|
|
189
|
+
# @return [Boolean] true if the version is stable
|
|
190
|
+
#
|
|
191
|
+
def self.stable?(version_string, scheme = nil)
|
|
192
|
+
Version.stable?(version_string, scheme)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
##
|
|
196
|
+
# Checks if a version is a prerelease using scheme-specific rules
|
|
197
|
+
#
|
|
198
|
+
# @param version_string [String] The version string to classify
|
|
199
|
+
# @param scheme [String, nil] Package manager scheme or nil for generic classification
|
|
200
|
+
# @return [Boolean] true if the version is a prerelease
|
|
201
|
+
#
|
|
202
|
+
def self.prerelease?(version_string, scheme = nil)
|
|
203
|
+
Version.prerelease?(version_string, scheme)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Returns a normalized version, or nil when the version is invalid.
|
|
207
|
+
#
|
|
208
|
+
# @param version_string [String] The version string to clean
|
|
209
|
+
# @param scheme [String, nil] Package manager scheme or nil for generic cleaning
|
|
210
|
+
# @return [String, nil] The normalized version or nil
|
|
211
|
+
#
|
|
212
|
+
def self.clean(version_string, scheme = nil)
|
|
213
|
+
Version.clean(version_string, scheme)
|
|
184
214
|
end
|
|
185
215
|
|
|
186
216
|
##
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Nesbitt
|
|
@@ -29,12 +29,23 @@ files:
|
|
|
29
29
|
- SECURITY.md
|
|
30
30
|
- VERSION-RANGE-SPEC.rst
|
|
31
31
|
- lib/vers.rb
|
|
32
|
+
- lib/vers/bazel_version.rb
|
|
33
|
+
- lib/vers/composer_version.rb
|
|
34
|
+
- lib/vers/conan_version.rb
|
|
32
35
|
- lib/vers/constraint.rb
|
|
36
|
+
- lib/vers/distribution_version.rb
|
|
37
|
+
- lib/vers/gem_version.rb
|
|
33
38
|
- lib/vers/interval.rb
|
|
34
39
|
- lib/vers/maven_version.rb
|
|
35
40
|
- lib/vers/nuget_version.rb
|
|
36
41
|
- lib/vers/parser.rb
|
|
42
|
+
- lib/vers/pub_version.rb
|
|
43
|
+
- lib/vers/pypi_version.rb
|
|
44
|
+
- lib/vers/scheme.rb
|
|
45
|
+
- lib/vers/semver_version.rb
|
|
46
|
+
- lib/vers/special_version.rb
|
|
37
47
|
- lib/vers/version.rb
|
|
48
|
+
- lib/vers/version_comparison.rb
|
|
38
49
|
- lib/vers/version_range.rb
|
|
39
50
|
- sig/vers.rbs
|
|
40
51
|
- test-suite-data.json
|
|
@@ -44,7 +55,7 @@ licenses:
|
|
|
44
55
|
metadata:
|
|
45
56
|
allowed_push_host: https://rubygems.org
|
|
46
57
|
homepage_uri: https://github.com/andrew/vers
|
|
47
|
-
source_code_uri: https://github.com/andrew/vers
|
|
58
|
+
source_code_uri: https://github.com/andrew/vers/tree/v2.0.0
|
|
48
59
|
changelog_uri: https://github.com/andrew/vers/blob/main/CHANGELOG.md
|
|
49
60
|
rdoc_options: []
|
|
50
61
|
require_paths:
|
|
@@ -53,14 +64,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
53
64
|
requirements:
|
|
54
65
|
- - ">="
|
|
55
66
|
- !ruby/object:Gem::Version
|
|
56
|
-
version: 3.
|
|
67
|
+
version: 3.3.0
|
|
57
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
69
|
requirements:
|
|
59
70
|
- - ">="
|
|
60
71
|
- !ruby/object:Gem::Version
|
|
61
72
|
version: '0'
|
|
62
73
|
requirements: []
|
|
63
|
-
rubygems_version: 4.0.
|
|
74
|
+
rubygems_version: 4.0.16
|
|
64
75
|
specification_version: 4
|
|
65
76
|
summary: A Ruby gem for parsing, comparing and sorting versions according to the VERS
|
|
66
77
|
spec.
|