vers 1.1.0 → 1.2.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/.gitmodules +3 -0
- data/lib/vers/parser.rb +74 -18
- data/lib/vers/version.rb +7 -5
- data/lib/vers.rb +13 -7
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8ad669b5ca951e8a64ddd205d39e083b3a9836a67ca9ff25d99872a57658a560
|
|
4
|
+
data.tar.gz: d1aefb9f16a5a842ad05d4e427b538a565240cf3c21969542bf614199e8e1955
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b87591c17a303bf820c2667f25ac802569173737c8bd63d13c86bc5aedf6e606cc50d3906c08d526dd8c9e934559f0cdc7717e8e6c4cfbd8ae5473ebc53bb9c
|
|
7
|
+
data.tar.gz: 9a6cafa4929f8a71b699d6ce1171e574bb6c99aca17b89850e7bf232d1269727d00f6a15f1b9a870f8319913e77b0ec865fc5633866161cb989425c9eefc76ce
|
data/.gitmodules
ADDED
data/lib/vers/parser.rb
CHANGED
|
@@ -109,16 +109,26 @@ module Vers
|
|
|
109
109
|
# @return [String] The vers URI string
|
|
110
110
|
#
|
|
111
111
|
def to_vers_string(version_range, scheme)
|
|
112
|
-
return "
|
|
112
|
+
return "vers:#{scheme}/*" if version_range.unbounded?
|
|
113
113
|
return "vers:#{scheme}/" if version_range.empty?
|
|
114
114
|
|
|
115
115
|
intervals = version_range.raw_constraints || version_range.intervals
|
|
116
116
|
constraints = []
|
|
117
117
|
|
|
118
|
+
# Detect != pattern: two intervals (-∞,V) ∪ (V,+∞)
|
|
119
|
+
if intervals.length == 2
|
|
120
|
+
a, b = intervals
|
|
121
|
+
if a.min.nil? && !a.max_inclusive && b.max.nil? && !b.min_inclusive && a.max == b.min
|
|
122
|
+
constraints << "!=#{a.max}"
|
|
123
|
+
constraints.sort_by! { |c| sort_key_for_constraint(c) }
|
|
124
|
+
return "vers:#{scheme}/#{constraints.join('|')}"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
118
128
|
intervals.each do |interval|
|
|
119
129
|
if interval.min == interval.max && interval.min_inclusive && interval.max_inclusive
|
|
120
130
|
# Exact version
|
|
121
|
-
constraints <<
|
|
131
|
+
constraints << interval.min.to_s
|
|
122
132
|
else
|
|
123
133
|
# Range constraints
|
|
124
134
|
if interval.min
|
|
@@ -134,7 +144,6 @@ module Vers
|
|
|
134
144
|
end
|
|
135
145
|
|
|
136
146
|
constraints.sort_by! { |c| sort_key_for_constraint(c) }
|
|
137
|
-
constraints.uniq!
|
|
138
147
|
|
|
139
148
|
"vers:#{scheme}/#{constraints.join('|')}"
|
|
140
149
|
end
|
|
@@ -144,7 +153,7 @@ module Vers
|
|
|
144
153
|
def sort_key_for_constraint(constraint)
|
|
145
154
|
version = constraint.sub(/\A[><=!]+/, '')
|
|
146
155
|
v = Version.cached_new(version)
|
|
147
|
-
[v
|
|
156
|
+
[v, constraint]
|
|
148
157
|
end
|
|
149
158
|
|
|
150
159
|
def parse_constraints(constraints_string, scheme)
|
|
@@ -164,8 +173,14 @@ module Vers
|
|
|
164
173
|
end
|
|
165
174
|
end
|
|
166
175
|
|
|
167
|
-
# Start with the union of all positive constraints
|
|
168
|
-
range =
|
|
176
|
+
# Start with the union of all positive constraints, or unbounded if only exclusions
|
|
177
|
+
range = if intervals.any?
|
|
178
|
+
VersionRange.new(intervals, scheme: interval_scheme)
|
|
179
|
+
elsif exclusions.any?
|
|
180
|
+
VersionRange.unbounded
|
|
181
|
+
else
|
|
182
|
+
VersionRange.new([], scheme: interval_scheme)
|
|
183
|
+
end
|
|
169
184
|
|
|
170
185
|
# Apply exclusions
|
|
171
186
|
exclusions.each do |version|
|
|
@@ -185,7 +200,7 @@ module Vers
|
|
|
185
200
|
# Handle || (OR) operator
|
|
186
201
|
if range_string.include?('||')
|
|
187
202
|
or_parts = range_string.split('||').map(&:strip)
|
|
188
|
-
ranges = or_parts.map { |part|
|
|
203
|
+
ranges = or_parts.map { |part| parse_npm_range(part) }
|
|
189
204
|
return ranges.reduce { |acc, range| acc.union(range) }
|
|
190
205
|
end
|
|
191
206
|
|
|
@@ -206,7 +221,13 @@ module Vers
|
|
|
206
221
|
end
|
|
207
222
|
end
|
|
208
223
|
ranges = merged.map { |part| parse_npm_single_range(part) }
|
|
209
|
-
|
|
224
|
+
# If all parts are bare versions (no operators), treat as union
|
|
225
|
+
all_exact = merged.all? { |part| part.match?(/\A\d/) }
|
|
226
|
+
if all_exact
|
|
227
|
+
ranges.reduce { |acc, range| acc.union(range) }
|
|
228
|
+
else
|
|
229
|
+
ranges.reduce { |acc, range| acc.intersect(range) }
|
|
230
|
+
end
|
|
210
231
|
end
|
|
211
232
|
|
|
212
233
|
def parse_npm_single_range(range_string)
|
|
@@ -256,8 +277,25 @@ module Vers
|
|
|
256
277
|
# Invalid patterns that should raise errors
|
|
257
278
|
raise ArgumentError, "Invalid NPM range format: #{range_string}"
|
|
258
279
|
else
|
|
280
|
+
# Check for operator + x-range (e.g. ">=2.2.x", ">=1.x")
|
|
281
|
+
if range_string.match(/\A[><=]+(\d+)\.[xX*]\z/)
|
|
282
|
+
major = $1.to_i
|
|
283
|
+
return VersionRange.new([
|
|
284
|
+
Interval.new(min: "#{major}.0.0", max: "#{major + 1}.0.0", min_inclusive: true, max_inclusive: false)
|
|
285
|
+
])
|
|
286
|
+
end
|
|
287
|
+
if range_string.match(/\A[><=]+(\d+)\.(\d+)\.[xX*]\z/)
|
|
288
|
+
major = $1.to_i
|
|
289
|
+
minor = $2.to_i
|
|
290
|
+
return VersionRange.new([
|
|
291
|
+
Interval.new(min: "#{major}.#{minor}.0", max: "#{major}.#{minor + 1}.0", min_inclusive: true, max_inclusive: false)
|
|
292
|
+
])
|
|
293
|
+
end
|
|
259
294
|
# Standard constraint
|
|
260
295
|
constraint = Constraint.parse(range_string)
|
|
296
|
+
# Normalize version to semver (npm always uses 3 segments)
|
|
297
|
+
normalized_version = Version.cached_new(constraint.version).to_s
|
|
298
|
+
constraint = Constraint.new(constraint.operator, normalized_version)
|
|
261
299
|
if constraint.exclusion?
|
|
262
300
|
VersionRange.unbounded.exclude(constraint.version)
|
|
263
301
|
else
|
|
@@ -289,9 +327,27 @@ module Vers
|
|
|
289
327
|
|
|
290
328
|
def parse_tilde_range(version)
|
|
291
329
|
v = Version.cached_new(version)
|
|
292
|
-
|
|
330
|
+
|
|
331
|
+
if v.prerelease
|
|
332
|
+
# ~0.8.0-pre := >=0.8.0-pre <0.8.0 OR >=0.8.0 <0.8.1
|
|
333
|
+
# Prereleases only match their own major.minor.patch
|
|
334
|
+
base = "#{v.major}.#{v.minor || 0}.#{v.patch || 0}"
|
|
335
|
+
next_patch = "#{v.major}.#{v.minor || 0}.#{(v.patch || 0) + 1}"
|
|
336
|
+
pre_range = VersionRange.new([
|
|
337
|
+
Interval.new(min: version, max: base, min_inclusive: true, max_inclusive: false)
|
|
338
|
+
])
|
|
339
|
+
release_range = VersionRange.new([
|
|
340
|
+
Interval.new(min: base, max: next_patch, min_inclusive: true, max_inclusive: false)
|
|
341
|
+
])
|
|
342
|
+
return pre_range.union(release_range)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
upper_version = if v.patch
|
|
293
346
|
# ~1.2.3 := >=1.2.3 <1.3.0
|
|
294
347
|
"#{v.major}.#{v.minor + 1}.0"
|
|
348
|
+
elsif v.minor
|
|
349
|
+
# ~1.2 := >=1.2.0 <1.3.0
|
|
350
|
+
"#{v.major}.#{v.minor + 1}.0"
|
|
295
351
|
else
|
|
296
352
|
# ~1 := >=1.0.0 <2.0.0
|
|
297
353
|
"#{v.major + 1}.0.0"
|
|
@@ -318,14 +374,14 @@ module Vers
|
|
|
318
374
|
def parse_pessimistic_range(version)
|
|
319
375
|
v = Version.cached_new(version)
|
|
320
376
|
upper_version = if v.patch
|
|
321
|
-
# ~> 1.2.3 := >= 1.2.3, < 1.3
|
|
322
|
-
"#{v.major}.#{v.minor + 1}
|
|
377
|
+
# ~> 1.2.3 := >= 1.2.3, < 1.3
|
|
378
|
+
"#{v.major}.#{v.minor + 1}"
|
|
323
379
|
elsif v.minor
|
|
324
|
-
# ~> 1.2 := >= 1.2.0, < 2
|
|
325
|
-
"#{v.major + 1}
|
|
380
|
+
# ~> 1.2 := >= 1.2.0, < 2
|
|
381
|
+
"#{v.major + 1}"
|
|
326
382
|
else
|
|
327
|
-
# ~> 1 := >= 1.0.0, < 2
|
|
328
|
-
"#{v.major + 1}
|
|
383
|
+
# ~> 1 := >= 1.0.0, < 2
|
|
384
|
+
"#{v.major + 1}"
|
|
329
385
|
end
|
|
330
386
|
|
|
331
387
|
VersionRange.new([
|
|
@@ -550,9 +606,9 @@ module Vers
|
|
|
550
606
|
end
|
|
551
607
|
|
|
552
608
|
def parse_hex_single_range(range_string)
|
|
553
|
-
# Handle "and" conjunction
|
|
554
|
-
if range_string.include?(" and ")
|
|
555
|
-
and_parts = range_string.split(
|
|
609
|
+
# Handle "and" conjunction and comma-separated AND constraints
|
|
610
|
+
if range_string.include?(" and ") || range_string.include?(",")
|
|
611
|
+
and_parts = range_string.split(/\s+and\s+|,/).map(&:strip).reject(&:empty?)
|
|
556
612
|
ranges = and_parts.map { |part| parse_hex_constraint(part) }
|
|
557
613
|
return ranges.reduce { |acc, range| acc.intersect(range) }
|
|
558
614
|
end
|
data/lib/vers/version.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Vers
|
|
4
|
-
VERSION = "1.
|
|
4
|
+
VERSION = "1.2.0"
|
|
5
5
|
|
|
6
6
|
##
|
|
7
7
|
# Handles version comparison and normalization across different package ecosystems.
|
|
@@ -104,10 +104,12 @@ module Vers
|
|
|
104
104
|
# @return [Boolean] true if the version is valid
|
|
105
105
|
#
|
|
106
106
|
def self.valid?(version_string)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
version_string.to_s.match?(/\Av?\d+\.\d+\.\d+/)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.clean(version_string)
|
|
111
|
+
return nil unless valid?(version_string)
|
|
112
|
+
version_string.to_s.sub(/\Av/, '')
|
|
111
113
|
end
|
|
112
114
|
|
|
113
115
|
##
|
data/lib/vers.rb
CHANGED
|
@@ -119,13 +119,15 @@ module Vers
|
|
|
119
119
|
# Vers.satisfies?("1.5.0", "^1.2.3", "npm") # => true
|
|
120
120
|
#
|
|
121
121
|
def self.satisfies?(version, constraint, scheme = nil)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
122
|
+
sub_ranges = constraint.split('||').map(&:strip).reject(&:empty?)
|
|
123
|
+
sub_ranges.any? do |sub_range|
|
|
124
|
+
range = if scheme
|
|
125
|
+
parse_native(sub_range, scheme)
|
|
126
|
+
else
|
|
127
|
+
parse(sub_range)
|
|
128
|
+
end
|
|
129
|
+
range.contains?(version)
|
|
130
|
+
end
|
|
129
131
|
end
|
|
130
132
|
|
|
131
133
|
##
|
|
@@ -177,6 +179,10 @@ module Vers
|
|
|
177
179
|
Version.valid?(version_string)
|
|
178
180
|
end
|
|
179
181
|
|
|
182
|
+
def self.clean(version_string)
|
|
183
|
+
Version.clean(version_string)
|
|
184
|
+
end
|
|
185
|
+
|
|
180
186
|
##
|
|
181
187
|
# Creates an exact version range
|
|
182
188
|
#
|
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: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Nesbitt
|
|
@@ -18,6 +18,7 @@ executables: []
|
|
|
18
18
|
extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
|
+
- ".gitmodules"
|
|
21
22
|
- ".ruby-version"
|
|
22
23
|
- CHANGELOG.md
|
|
23
24
|
- CODE_OF_CONDUCT.md
|