Skip to content

Commit 2bf9d59

Browse files
authored
CDRIVER-4759 Define Version in calc_release_version.py. (#1460)
* add simple `Version` class * add self test of version sorting * revise self-test comment * update version in self-test * fix directory in self test comment
1 parent 25f6bdf commit 2bf9d59

File tree

3 files changed

+66
-27
lines changed

3 files changed

+66
-27
lines changed

build/calc_release_version.py

+47-25
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,9 @@
2727
"""
2828

2929
# XXX NOTE XXX NOTE XXX NOTE XXX
30-
# After modifying this script it is advisable to execute the self-test.
31-
#
32-
# This is done by starting in the directory containing this script and then
33-
# executing a separate self-test script, like this:
34-
#
35-
# $ bash ./calc_release_version_selftest.sh
36-
#
37-
# The self-test script will emit diagnostic output. If tracing of the execution
38-
# of each command is desired, then add the -x option to the bash invocation.
30+
# After modifying this script it is advisable to execute the self-tests in this directory:
31+
# - calc_release_version_selftest.sh
32+
# - calc_release_version_selftest.py
3933
# XXX NOTE XXX NOTE XXX NOTE XXX
4034

4135
# pyright: reportTypeCommentUsage=false
@@ -47,19 +41,46 @@
4741
import optparse # No 'argparse' on Python 2.6
4842
import sys
4943

50-
try:
51-
# Prefer newer `packaging` over deprecated packages.
52-
from packaging.version import Version as Version
53-
from packaging.version import parse as parse_version
54-
except ImportError:
55-
# Fallback to deprecated pkg_resources.
56-
try:
57-
from pkg_resources.extern.packaging.version import Version # type: ignore
58-
from pkg_resources import parse_version
59-
except ImportError:
60-
# Fallback to deprecated distutils.
61-
from distutils.version import LooseVersion as Version
62-
from distutils.version import LooseVersion as parse_version
44+
45+
class Version:
46+
def __init__(self, s):
47+
pat = r'(\d+)\.(\d+)\.(\d+)(\-\S+)?'
48+
match = re.match(pat, s)
49+
assert match, "Unrecognized version string %s" % s
50+
self.major, self.minor, self.micro = (
51+
map(int, (match.group(1), match.group(2), match.group(3))))
52+
53+
if match.group(4):
54+
self.prerelease = match.group(4)[1:]
55+
else:
56+
self.prerelease = ''
57+
58+
def __lt__(self, other):
59+
if self.major != other.major:
60+
return self.major < other.major
61+
if self.minor != other.minor:
62+
return self.minor < other.minor
63+
if self.micro != other.micro:
64+
return self.micro < other.micro
65+
if self.prerelease != other.prerelease:
66+
if self.prerelease != '' and other.prerelease == '':
67+
# Consider a prerelease less than non-prerelease.
68+
return True
69+
# For simplicity, compare prerelease versions lexicographically.
70+
return self.prerelease < other.prerelease
71+
72+
# Versions are equal.
73+
return False
74+
75+
def __eq__(self, other):
76+
self_tuple = self.major, self.minor, self.micro, self.prerelease
77+
other_tuple = other.major, other.minor, other.micro, other.prerelease
78+
return self_tuple == other_tuple
79+
80+
81+
def parse_version(ver):
82+
return Version(ver)
83+
6384

6485
parser = optparse.OptionParser(description=__doc__)
6586
parser.add_option("--debug", "-d", action="store_true", help="Enable debug output")
@@ -375,7 +396,8 @@ def previous(rel_ver): # type: (str) -> str
375396

376397
return version_str
377398

378-
RELEASE_VER = previous(main()) if PREVIOUS else main()
399+
if __name__ == "__main__":
400+
RELEASE_VER = previous(main()) if PREVIOUS else main()
379401

380-
debug('Final calculated release version:')
381-
print(RELEASE_VER)
402+
debug('Final calculated release version:')
403+
print(RELEASE_VER)
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import unittest
2+
import calc_release_version
3+
4+
5+
class TestVersionSort(unittest.TestCase):
6+
def test_version_sort(self):
7+
# At time of writing, `input_tags` is the output of `git tag -l "1.*"`:
8+
input_tags = ["1.0.0", "1.0.2", "1.1.0", "1.1.0-rc0", "1.1.10", "1.1.11", "1.1.2", "1.1.4", "1.1.5", "1.1.6", "1.1.7", "1.1.8", "1.1.9", "1.10.0", "1.10.1", "1.10.2", "1.10.3", "1.11.0", "1.12.0", "1.13.0", "1.13.1", "1.14.0", "1.14.1", "1.15.0", "1.15.1", "1.15.2", "1.15.3", "1.16.0", "1.16.1", "1.16.2", "1.17.0", "1.17.0-beta", "1.17.0-beta2", "1.17.0-rc0", "1.17.1", "1.17.2", "1.17.3", "1.17.4", "1.17.5", "1.17.6", "1.17.7", "1.18.0", "1.18.0-alpha", "1.18.0-alpha2", "1.19.0", "1.19.1", "1.19.2", "1.2.0", "1.2.0-beta", "1.2.0-beta1", "1.2.0-rc0", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.20.0", "1.20.1", "1.21.0", "1.21.1", "1.21.2", "1.22.0", "1.22.0-beta0", "1.22.1", "1.22.2", "1.23.0",
9+
"1.23.1", "1.23.2", "1.23.3", "1.23.4", "1.23.5", "1.24.0", "1.24.1", "1.24.2", "1.24.3", "1.24.4", "1.3.0", "1.3.0-beta0", "1.3.0-rc0", "1.3.1", "1.3.2", "1.3.3", "1.3.4", "1.3.5", "1.3.6", "1.4.0", "1.4.0-beta0", "1.4.0-beta1", "1.4.1", "1.4.2", "1.4.3", "1.5.0", "1.5.0-rc0", "1.5.0-rc1", "1.5.0-rc2", "1.5.0-rc3", "1.5.0-rc4", "1.5.0-rc6", "1.5.1", "1.5.2", "1.5.3", "1.5.4", "1.5.5", "1.6.0", "1.6.0-rc0", "1.6.1", "1.6.2", "1.6.3", "1.7.0", "1.7.0-rc0", "1.7.0-rc1", "1.7.0-rc2", "1.8.0", "1.8.0-rc0", "1.8.0-rc1", "1.8.1", "1.8.2", "1.9.0", "1.9.0+dfsg", "1.9.0-rc0", "1.9.0-rc1", "1.9.1", "1.9.2", "1.9.2+dfsg", "1.9.3", "1.9.3+dfsg", "1.9.4", "1.9.4+dfsg", "1.9.5", "1.9.5+dfsg"]
10+
expected_tags = ['1.0.0', '1.0.2', '1.1.0-rc0', '1.1.0', '1.1.2', '1.1.4', '1.1.5', '1.1.6', '1.1.7', '1.1.8', '1.1.9', '1.1.10', '1.1.11', '1.2.0-beta', '1.2.0-beta1', '1.2.0-rc0', '1.2.0', '1.2.1', '1.2.2', '1.2.3', '1.2.4', '1.3.0-beta0', '1.3.0-rc0', '1.3.0', '1.3.1', '1.3.2', '1.3.3', '1.3.4', '1.3.5', '1.3.6', '1.4.0-beta0', '1.4.0-beta1', '1.4.0', '1.4.1', '1.4.2', '1.4.3', '1.5.0-rc0', '1.5.0-rc1', '1.5.0-rc2', '1.5.0-rc3', '1.5.0-rc4', '1.5.0-rc6', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '1.5.5', '1.6.0-rc0', '1.6.0', '1.6.1', '1.6.2', '1.6.3', '1.7.0-rc0', '1.7.0-rc1', '1.7.0-rc2', '1.7.0', '1.8.0-rc0', '1.8.0-rc1', '1.8.0', '1.8.1', '1.8.2', '1.9.0-rc0', '1.9.0-rc1',
11+
'1.9.0', '1.9.0+dfsg', '1.9.1', '1.9.2', '1.9.2+dfsg', '1.9.3', '1.9.3+dfsg', '1.9.4', '1.9.4+dfsg', '1.9.5', '1.9.5+dfsg', '1.10.0', '1.10.1', '1.10.2', '1.10.3', '1.11.0', '1.12.0', '1.13.0', '1.13.1', '1.14.0', '1.14.1', '1.15.0', '1.15.1', '1.15.2', '1.15.3', '1.16.0', '1.16.1', '1.16.2', '1.17.0-beta', '1.17.0-beta2', '1.17.0-rc0', '1.17.0', '1.17.1', '1.17.2', '1.17.3', '1.17.4', '1.17.5', '1.17.6', '1.17.7', '1.18.0-alpha', '1.18.0-alpha2', '1.18.0', '1.19.0', '1.19.1', '1.19.2', '1.20.0', '1.20.1', '1.21.0', '1.21.1', '1.21.2', '1.22.0-beta0', '1.22.0', '1.22.1', '1.22.2', '1.23.0', '1.23.1', '1.23.2', '1.23.3', '1.23.4', '1.23.5', '1.24.0', '1.24.1', '1.24.2', '1.24.3', '1.24.4']
12+
got_tags = sorted(input_tags, key=calc_release_version.Version)
13+
self.assertEqual(got_tags, expected_tags)
14+
15+
16+
if __name__ == "__main__":
17+
unittest.main()

build/calc_release_version_selftest.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/bash
22
# calc_release_version_selftest.sh is used to test output of calc_release_version.py.
33
# run with:
4-
# cd etc
4+
# cd build
55
# ./calc_release_version_selftest.sh
66

77
set -o errexit
@@ -77,7 +77,7 @@ echo "Test next minor version ... begin"
7777
# failed, then it is probably because a new major/minor release was made.
7878
# Update the expected output to represent the correct next version.
7979
# XXX NOTE XXX NOTE XXX
80-
assert_eq "$got" "1.24.1"
80+
assert_eq "$got" "1.24.4"
8181
}
8282
echo "Test next minor version ... end"
8383

0 commit comments

Comments
 (0)