diff --git a/kolibri/utils/tests/test_version.py b/kolibri/utils/tests/test_version.py index 2da5bc34ac9..db6f31f1e7a 100755 --- a/kolibri/utils/tests/test_version.py +++ b/kolibri/utils/tests/test_version.py @@ -200,6 +200,22 @@ def test_normalize_version_to_semver_beta(self): "0.16-b.1", ) + def test_normalize_version_to_semver_scm_dev(self): + self.assertEqual( + version.normalize_version_to_semver( + "0.1.2.dev6+gdef09150", + ), + "0.1.2-dev6.gdef09150", + ) + + def test_normalize_version_to_semver_bipartite_dev(self): + self.assertEqual( + version.normalize_version_to_semver( + "0.1.dev38363+g356cfe2f5", + ), + "0.1.0-dev38363.g356cfe2f5", + ) + @parameterized.expand( [ ("0.15.8", ">=0.15.8", True), diff --git a/kolibri/utils/version.py b/kolibri/utils/version.py index d7823d90b8e..828e9525f83 100644 --- a/kolibri/utils/version.py +++ b/kolibri/utils/version.py @@ -50,16 +50,22 @@ def version_matches_range(version, version_range): def normalize_version_to_semver(version): - # dev = re.match(r"(.*?)(\.dev.*)?$", version).group() dev_match = re.match(r"(.*?)(\.dev.*)?$", version) - + pre_dev = dev_match.group(1) dev = dev_match.group(2) - # extract the numeric semver component and the stuff that comes after + # extract numeric and prerelease from pre_dev + m = re.match(r"(^\d+\.\d+(?:\.\d+)?)([a-z0-9.+]*)", pre_dev) + if m: + numeric, after = m.groups() + else: + numeric, after = re.match( + r"(^\d+\.\d+[0-9]*\.?[0-9]*)([a-z0-9.+]*)", version + ).groups() - numeric, after = re.match( - r"(^\d+\.\d+[0-9]*\.?[0-9]*)([a-z0-9.+]*)", version - ).groups() + # If bipartite and followed by dev, ensure a patch segment exists for semver + if numeric.count(".") == 1 and dev: + numeric = numeric + ".0" # clean up the different variations of the post-numeric component to ease checking after = (after or "").strip("-").strip("+").strip(".").split("+")[0] @@ -72,7 +78,16 @@ def normalize_version_to_semver(version): # make sure dev versions are sorted nicely relative to one another dev = (dev or "").replace("+", ".").replace("-", ".") - return "{}-{}{}".format(numeric, after, dev).strip("-") + if after and dev: + suffix = after + dev + elif after: + suffix = after + elif dev: + suffix = dev.lstrip(".") + else: + suffix = "" + + return "{}-{}".format(numeric, suffix) if suffix else numeric def truncate_version(version, truncation_level=PATCH_VERSION):