Skip to content

Commit d3c8797

Browse files
committed
Fix Npm version range #79
Reference: #79 Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent cce7806 commit d3c8797

3 files changed

Lines changed: 5360 additions & 28 deletions

File tree

src/univers/version_range.py

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,41 @@ def from_osv_v1(data, scheme):
223223
"""
224224

225225

226+
def get_allof_constraints(cls, clause):
227+
"""
228+
Return a list of VersionConstraint given an AllOf ``clause``.
229+
"""
230+
if not isinstance(clause, AllOf):
231+
raise ValueError(f"Unknown clause type: {clause!r}")
232+
allof_constraints = []
233+
for constraint in clause.clauses:
234+
comparator = cls.vers_by_native_comparators[constraint.operator]
235+
version = cls.version_class(str(constraint.target))
236+
constraint = VersionConstraint(comparator=comparator, version=version)
237+
allof_constraints.append(constraint)
238+
return allof_constraints
239+
240+
241+
def get_npm_version_constraint_for_tilde_and_caret(string, cls):
242+
"""
243+
Return a VersionConstraint for the provided ``string``.
244+
"""
245+
spec = semantic_version.NpmSpec(string)
246+
clause = spec.clause.simplify()
247+
if isinstance(clause, (AnyOf, AllOf)):
248+
anyof_constraints = []
249+
if isinstance(clause, AnyOf):
250+
for allof_clause in clause.clauses:
251+
anyof_constraints.extend(get_allof_constraints(cls, allof_clause))
252+
elif isinstance(clause, AllOf):
253+
alloc = get_allof_constraints(cls, clause)
254+
anyof_constraints.extend(alloc)
255+
else:
256+
raise ValueError(f"Unknown clause type: {spec!r}")
257+
258+
return anyof_constraints
259+
260+
226261
class NpmVersionRange(VersionRange):
227262
scheme = "npm"
228263
version_class = versions.SemverVersion
@@ -245,35 +280,49 @@ def from_native(cls, string):
245280

246281
# an NpmSpec handles parsing of both the semver versions and node-semver
247282
# ranges at once
248-
spec = semantic_version.NpmSpec(string)
249-
250-
clause = spec.clause.simplify()
251-
assert isinstance(clause, (AnyOf, AllOf))
252-
anyof_constraints = []
253-
if isinstance(clause, AnyOf):
254-
for allof_clause in clause.clauses:
255-
anyof_constraints.extend(get_allof_constraints(cls, allof_clause))
256-
elif isinstance(clause, AllOf):
257-
alloc = get_allof_constraints(cls, clause)
258-
anyof_constraints.extend(alloc)
259-
else:
260-
raise ValueError(f"Unknown clause type: {spec!r}")
261-
262-
return cls(constraints=anyof_constraints)
263283

284+
if string == "*":
285+
return cls(
286+
constraints=[
287+
VersionConstraint.from_string(string="*", version_class=cls.version_class)
288+
]
289+
)
264290

265-
def get_allof_constraints(cls, clause):
266-
"""
267-
Return a list of VersionConstraint given an AllOf ``clause``.
268-
"""
269-
assert isinstance(clause, AllOf)
270-
allof_constraints = []
271-
for constraint in clause.clauses:
272-
comparator = cls.vers_by_native_comparators[constraint.operator]
273-
version = cls.version_class(str(constraint.target))
274-
constraint = VersionConstraint(comparator=comparator, version=version)
275-
allof_constraints.append(constraint)
276-
return allof_constraints
291+
constraints = []
292+
comparator = ""
293+
vrc = cls.version_class
294+
# A constraint item can be a comparator or a version or a version with comparator
295+
# If it's empty continue
296+
# If it's in `vers_by_native_comparators`, append it with the comparator and continue
297+
# If it's a version, make version constraint from the version and use the comparator from the previous item and make comparator empty
298+
# If it's a version with comparator, use split_req to get version and comparator to form constraint and make comparator empty
299+
for constraint_item in string.split(" "):
300+
if not constraint_item or constraint_item == "||":
301+
continue
302+
if "".join([comparator, constraint_item]) in cls.vers_by_native_comparators:
303+
comparator = "".join([comparator, constraint_item])
304+
comparator = cls.vers_by_native_comparators[comparator]
305+
continue
306+
if comparator:
307+
constraint_item = constraint_item.lstrip("vV")
308+
constraints.append(
309+
VersionConstraint(comparator=comparator, version=vrc(constraint_item))
310+
)
311+
else:
312+
if constraint_item.startswith("~") or constraint_item.startswith("^"):
313+
constraints.extend(
314+
get_npm_version_constraint_for_tilde_and_caret(constraint_item, cls)
315+
)
316+
else:
317+
comparator, version_constraint = split_req(
318+
constraint_item, cls.vers_by_native_comparators, default="="
319+
)
320+
version_constraint = version_constraint.lstrip("vV")
321+
constraints.append(
322+
VersionConstraint(comparator=comparator, version=vrc(version_constraint))
323+
)
324+
comparator = ""
325+
return cls(constraints=constraints)
277326

278327

279328
class GemVersionRange(VersionRange):

0 commit comments

Comments
 (0)