Skip to content

Commit 2f81985

Browse files
committed
Merge remote-tracking branch 'origin/main' into nuget-versions
2 parents d5ee2ec + 0b357c7 commit 2f81985

9 files changed

Lines changed: 25865 additions & 24 deletions

File tree

CHANGELOG.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@ Changelog
22
=========
33

44

5+
Version v30.7.0
6+
----------------
7+
8+
- Add composer and golang versions and also support gitlab native ranges for them
9+
10+
11+
Version v30.6.0
12+
----------------
13+
14+
- Add support for gitlab in pypi, npm, gem version ranges
15+
- Subclass semver for nginx
16+
17+
518
Version v30.5.1
619
----------------
720

src/univers/version_range.py

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class NpmVersionRange(VersionRange):
233233
">=": ">=",
234234
"<": "<",
235235
">": ">",
236+
"=": "=", # This is not a native node-semver comparator, but is used in the gitlab version range for npm packages.
236237
}
237238

238239
@classmethod
@@ -663,7 +664,16 @@ class ComposerVersionRange(VersionRange):
663664
# TODO composer may need its own scheme see https//github.com/nexB/univers/issues/5
664665
# and https//getcomposer.org/doc/articles/versions.md
665666
scheme = "composer"
666-
version_class = versions.SemverVersion
667+
version_class = versions.ComposerVersion
668+
669+
vers_by_native_comparators = {
670+
"==": "=",
671+
"<=": "<=",
672+
">=": ">=",
673+
"<": "<",
674+
">": ">",
675+
"=": "=", # This is not a native composer-semver comparator, but is used in the gitlab version range for composer packages.
676+
}
667677

668678

669679
class RpmVersionRange(VersionRange):
@@ -756,7 +766,16 @@ class GolangVersionRange(VersionRange):
756766
"""
757767

758768
scheme = "golang"
759-
version_class = versions.SemverVersion
769+
version_class = versions.GolangVersion
770+
771+
vers_by_native_comparators = {
772+
"==": "=",
773+
"<=": "<=",
774+
">=": ">=",
775+
"<": "<",
776+
">": ">",
777+
"=": "=", # This is not a native golang-semver comparator, but is used in the gitlab version range for go packages.
778+
}
760779

761780

762781
class GenericVersionRange(VersionRange):
@@ -857,7 +876,7 @@ class NginxVersionRange(VersionRange):
857876
"""
858877

859878
scheme = "nginx"
860-
version_class = versions.SemverVersion
879+
version_class = versions.NginxVersion
861880

862881
vers_by_native_comparators = {
863882
"==": "=",
@@ -919,12 +938,10 @@ def from_native(cls, string):
919938
# suffixed version
920939
vs = clauses.rstrip("+")
921940
version = cls.version_class(vs)
922-
is_stable = is_even(version.value.minor)
923-
924-
if is_stable:
941+
if version.is_stable:
925942
# we have a start and end in stable ranges
926943
start_version = cls.version_class(vs)
927-
end_version = cls.version_class(str(start_version.value.next_minor()))
944+
end_version = cls.version_class(str(start_version.next_minor()))
928945
vstart = VersionConstraint(comparator=">=", version=start_version)
929946
vend = VersionConstraint(comparator="<", version=end_version)
930947
constraints.extend([vstart, vend])
@@ -974,6 +991,49 @@ def from_native(cls, string):
974991
return cls(constraints=constraints)
975992

976993

994+
def from_gitlab_native(gitlab_scheme, string):
995+
purl_scheme = PURL_TYPE_BY_GITLAB_SCHEME[gitlab_scheme]
996+
vrc = RANGE_CLASS_BY_SCHEMES[purl_scheme]
997+
constraint_items = []
998+
constraints = []
999+
split = " "
1000+
split_by_comma_schemes = ["pypi", "composer"]
1001+
if purl_scheme in split_by_comma_schemes:
1002+
split = ","
1003+
pipe_separated_constraints = string.split("||")
1004+
for pipe_separated_constraint in pipe_separated_constraints:
1005+
space_seperated_constraints = pipe_separated_constraint.split(split)
1006+
constraint_items.extend(space_seperated_constraints)
1007+
comparator = ""
1008+
# A constraint item can be a comparator or a version or a version with comparator
1009+
# If it's empty continue
1010+
# If it's in `vers_by_native_comparators`, append it with the comparator and continue
1011+
# If it's a version, make version constraint from the version and use the comparator from the previous item and make comparator empty
1012+
# If it's a version with comparator, use split_req to get version and comparator to form constraint and make comparator empty
1013+
for constraint_item in constraint_items:
1014+
if not constraint_item:
1015+
continue
1016+
if "".join([comparator, constraint_item]) in vrc.vers_by_native_comparators:
1017+
comparator = "".join([comparator, constraint_item])
1018+
comparator = vrc.vers_by_native_comparators[comparator]
1019+
continue
1020+
if comparator:
1021+
constraints.append(
1022+
VersionConstraint(comparator=comparator, version=vrc.version_class(constraint_item))
1023+
)
1024+
else:
1025+
comparator, version_constraint = split_req(
1026+
constraint_item, vrc.vers_by_native_comparators, default="="
1027+
)
1028+
constraints.append(
1029+
VersionConstraint(
1030+
comparator=comparator, version=vrc.version_class(version_constraint)
1031+
)
1032+
)
1033+
comparator = ""
1034+
return vrc(constraints=constraints)
1035+
1036+
9771037
vers_by_github_native_comparators = {
9781038
"=": "=",
9791039
"!=": "!=",
@@ -1036,21 +1096,6 @@ def build_range_from_github_advisory_constraint(scheme: str, string: str):
10361096
return vrc(constraints=constraints)
10371097

10381098

1039-
def is_even(s):
1040-
"""
1041-
Return True if the string "s" is an even number and False if this is an odd
1042-
number. For example:
1043-
1044-
>>> is_even(4)
1045-
True
1046-
>>> is_even(123)
1047-
False
1048-
>>> is_even(0)
1049-
True
1050-
"""
1051-
return (int(s) % 2) == 0
1052-
1053-
10541099
RANGE_CLASS_BY_SCHEMES = {
10551100
"npm": NpmVersionRange,
10561101
"deb": DebianVersionRange,
@@ -1072,3 +1117,13 @@ def is_even(s):
10721117
"nginx": NginxVersionRange,
10731118
"openssl": OpensslVersionRange,
10741119
}
1120+
1121+
PURL_TYPE_BY_GITLAB_SCHEME = {
1122+
"gem": "gem",
1123+
"go": "golang",
1124+
"maven": "maven",
1125+
"npm": "npm",
1126+
"nuget": "nuget",
1127+
"pypi": "pypi",
1128+
"packagist": "composer",
1129+
}

src/univers/versions.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,64 @@ def is_valid(cls, string):
219219
except ValueError:
220220
return False
221221

222+
@property
223+
def major(self):
224+
return self.value and self.value.major
225+
226+
@property
227+
def minor(self):
228+
return self.value and self.value.minor
229+
230+
@property
231+
def patch(self):
232+
return self.value and self.value.patch
233+
234+
@property
235+
def prerelease(self):
236+
return self.value and self.value.prerelease
237+
238+
@property
239+
def build(self):
240+
return self.value and self.value.build
241+
242+
def next_major(self):
243+
return self.value and self.value.next_major()
244+
245+
def next_minor(self):
246+
return self.value and self.value.next_minor()
247+
248+
def next_patch(self):
249+
return self.value and self.value.next_patch()
250+
251+
252+
def is_even(s):
253+
"""
254+
Return True if the string "s" is an even number and False if this is an odd
255+
number. For example:
256+
257+
>>> is_even(4)
258+
True
259+
>>> is_even(123)
260+
False
261+
>>> is_even(0)
262+
True
263+
"""
264+
return (int(s) % 2) == 0
265+
266+
267+
@attr.s(frozen=True, order=False, eq=False, hash=True)
268+
class NginxVersion(SemverVersion):
269+
"""
270+
Semver with 3 segments and extra attribute for stable vs. unstable branches
271+
"""
272+
273+
@property
274+
def is_stable(self):
275+
"""
276+
True if this is a "stable "version
277+
"""
278+
return is_even(self.minor)
279+
222280

223281
@attr.s(frozen=True, order=False, eq=False, hash=True)
224282
class RubygemsVersion(Version):
@@ -369,6 +427,20 @@ def __gt__(self, other):
369427
return gentoo.vercmp(self.value, other.value) > 0
370428

371429

430+
@attr.s(frozen=True, order=False, eq=False, hash=True)
431+
class ComposerVersion(SemverVersion):
432+
@classmethod
433+
def build_value(cls, string):
434+
return semantic_version.Version.coerce(string.lstrip("vV"))
435+
436+
437+
@attr.s(frozen=True, order=False, eq=False, hash=True)
438+
class GolangVersion(SemverVersion):
439+
@classmethod
440+
def build_value(cls, string):
441+
return semantic_version.Version.coerce(string.lstrip("vV"))
442+
443+
372444
@attr.s(frozen=True, order=False, eq=False, hash=True)
373445
class LegacyOpensslVersion(Version):
374446
"""

0 commit comments

Comments
 (0)