Skip to content

Commit 168e7a6

Browse files
committed
intdot versioning scheme
Signed-off-by: Kunz, Immanuel <[email protected]>
1 parent 9c15915 commit 168e7a6

File tree

5 files changed

+153
-0
lines changed

5 files changed

+153
-0
lines changed

src/univers/intdot.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Visit https://aboutcode.org and https://github.com/aboutcode-org/univers for support and download.
4+
5+
import re
6+
7+
8+
class IntdotVersion:
9+
"""
10+
intdot version.
11+
12+
The regex pattern for the intdot version is any number (>0) of integers separated by dots, followed by an arbitrary number of other characters, e.g., 1.2.3.5543, 123.234-prerelease, 1.2.3alpha
13+
"""
14+
15+
VERSION_PATTERN = r"^(\d+(\.\d+)*)(.*)$"
16+
17+
def __init__(self, version):
18+
if not self.is_valid(version):
19+
raise InvalidVersionError(version)
20+
21+
version = str(version).strip()
22+
self.original = version
23+
24+
def __eq__(self, other):
25+
return self.original == other.original
26+
27+
def __lt__(self, other):
28+
return self.__cmp__(other) < 0
29+
30+
def __le__(self, other):
31+
return self.__cmp__(other) <= 0
32+
33+
def __gt__(self, other):
34+
return self.__cmp__(other) > 0
35+
36+
def __ge__(self, other):
37+
return self.__cmp__(other) >= 0
38+
39+
@classmethod
40+
def is_valid(cls, string):
41+
return re.compile(IntdotVersion.VERSION_PATTERN).match(string)
42+
43+
def extract_numeric_labels(self, version):
44+
"""
45+
Check if the version matches the pattern; if it matches, extract the first group (identified by parentheses) which is the numeric part of the version
46+
"""
47+
match = re.match(IntdotVersion.VERSION_PATTERN, version)
48+
49+
if match:
50+
version_labels = match.group(1)
51+
return version_labels
52+
else:
53+
raise InvalidVersionError(version)
54+
55+
def __cmp__(self, other):
56+
"""
57+
Compare this version with ``other`` returning -1, 0, or 1 if the
58+
other version is larger, the same, or smaller than this
59+
one.
60+
"""
61+
if isinstance(other, str):
62+
other = IntdotVersion(other)
63+
64+
if not isinstance(other, IntdotVersion):
65+
raise InvalidVersionError
66+
67+
if self.original == other.original:
68+
return 0
69+
70+
lhlabels = self.extract_numeric_labels(self.original)
71+
rhlabels = self.extract_numeric_labels(other.original)
72+
73+
if lhlabels == rhlabels:
74+
return 0
75+
76+
lhsize = len(lhlabels)
77+
rhsize = len(rhlabels)
78+
79+
if lhsize > rhsize:
80+
limit = lhsize
81+
else:
82+
limit = rhsize
83+
84+
limit -= 1
85+
86+
i = 0
87+
88+
while i <= limit:
89+
try:
90+
lhs = lhlabels[i]
91+
except IndexError:
92+
lhs = 0
93+
94+
try:
95+
rhs = rhlabels[i]
96+
except IndexError:
97+
rhs = 0
98+
99+
i += 1
100+
101+
if lhs == rhs:
102+
continue
103+
104+
if int(lhs) > int(rhs):
105+
return 1
106+
if int(lhs) < int(rhs):
107+
return -1
108+
return 0
109+
110+
111+
class InvalidVersionError(ValueError):
112+
pass

src/univers/version_range.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,11 @@ class GolangVersionRange(VersionRange):
959959
}
960960

961961

962+
class IntdotVersionRange(VersionRange):
963+
scheme = "intdot"
964+
version_class = versions.IntdotVersion
965+
966+
962967
class GenericVersionRange(VersionRange):
963968
scheme = "generic"
964969
version_class = versions.SemverVersion
@@ -1419,6 +1424,7 @@ def build_range_from_snyk_advisory_string(scheme: str, string: Union[str, List])
14191424
"openssl": OpensslVersionRange,
14201425
"mattermost": MattermostVersionRange,
14211426
"conan": ConanVersionRange,
1427+
"intdot": IntdotVersionRange,
14221428
}
14231429

14241430
PURL_TYPE_BY_GITLAB_SCHEME = {

src/univers/versions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from univers import debian
1313
from univers import gem
1414
from univers import gentoo
15+
from univers import intdot
1516
from univers import maven
1617
from univers import nuget
1718
from univers import rpm
@@ -133,6 +134,16 @@ def __str__(self):
133134
return str(self.value)
134135

135136

137+
class IntdotVersion(Version):
138+
@classmethod
139+
def build_value(cls, string):
140+
return intdot.IntdotVersion(string)
141+
142+
@classmethod
143+
def is_valid(cls, string):
144+
return intdot.IntdotVersion.is_valid(string)
145+
146+
136147
class GenericVersion(Version):
137148
@classmethod
138149
def is_valid(cls, string):
@@ -702,4 +713,5 @@ def bump(self, index):
702713
OpensslVersion,
703714
LegacyOpensslVersion,
704715
AlpineLinuxVersion,
716+
IntdotVersion,
705717
]

tests/test_version_range.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from univers.version_range import RANGE_CLASS_BY_SCHEMES
1414
from univers.version_range import ConanVersionRange
1515
from univers.version_range import GemVersionRange
16+
from univers.version_range import IntdotVersionRange
1617
from univers.version_range import InvalidVersionRange
1718
from univers.version_range import MattermostVersionRange
1819
from univers.version_range import NpmVersionRange
@@ -22,6 +23,7 @@
2223
from univers.version_range import VersionRange
2324
from univers.version_range import build_range_from_snyk_advisory_string
2425
from univers.version_range import from_gitlab_native
26+
from univers.versions import IntdotVersion
2527
from univers.versions import InvalidVersion
2628
from univers.versions import NugetVersion
2729
from univers.versions import OpensslVersion
@@ -546,3 +548,12 @@ def test_version_range_normalize_case3():
546548
nvr = vr.normalize(known_versions=known_versions)
547549

548550
assert str(nvr) == "vers:pypi/>=1.0.0|<=1.3.0|3.0.0"
551+
552+
553+
def test_version_range_intdot():
554+
intdot_range = IntdotVersionRange.from_string("vers:intdot/>1.2.3.4")
555+
assert IntdotVersion("1.3.3") in intdot_range
556+
assert IntdotVersion("0.3.3") not in intdot_range
557+
assert IntdotVersion("1.3.3alpha") in intdot_range
558+
assert IntdotVersion("1.2.2.pre") not in intdot_range
559+
assert IntdotVersion("1010.23.234203.0") in IntdotVersionRange.from_string("vers:intdot/*")

tests/test_versions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from univers.versions import EnhancedSemanticVersion
1313
from univers.versions import GentooVersion
1414
from univers.versions import GolangVersion
15+
from univers.versions import IntdotVersion
1516
from univers.versions import MavenVersion
1617
from univers.versions import NginxVersion
1718
from univers.versions import NugetVersion
@@ -218,3 +219,14 @@ def test_golang_version():
218219
assert GolangVersion("v0.1.1") >= GolangVersion("v0.1.1")
219220
assert GolangVersion("v0.1.1") <= GolangVersion("v0.1.1")
220221
assert GolangVersion("v0.1.1") <= GolangVersion("v0.1.2")
222+
223+
224+
def test_intdot_version():
225+
assert IntdotVersion("1.2.3.4.5") == IntdotVersion("1.2.3.4.5")
226+
assert IntdotVersion("1.2.3.4.6") > IntdotVersion("1.2.3.4.5")
227+
assert IntdotVersion("1.2.3.4.6") < IntdotVersion("2.2.3.4.5")
228+
assert IntdotVersion("1.2.3.4.6") <= IntdotVersion("2.2.3.4.5")
229+
assert IntdotVersion("1.2.3.4.6-pre") <= IntdotVersion("2.2.3.4.5")
230+
assert IntdotVersion("1.2.3.4.6-pre") <= IntdotVersion("2.2.3.4.5.pre")
231+
assert IntdotVersion("1.2.3.4.6-pre") <= IntdotVersion("2.2.3.4.5-10")
232+
assert IntdotVersion("1.2.3.4.6-pre") <= IntdotVersion("2.2.3.4.5-10")

0 commit comments

Comments
 (0)