BUG: Better support PEP440 style plugin versions

This commit is contained in:
Thomas JANVIER 2025-01-16 16:43:41 +01:00 committed by Nyall Dawson
parent 0add86b7fa
commit 82a87520ab
2 changed files with 38 additions and 24 deletions

View File

@ -56,6 +56,7 @@ import re
def normalizeVersion(s): def normalizeVersion(s):
"""remove possible prefix from given string and convert to uppercase""" """remove possible prefix from given string and convert to uppercase"""
prefixes = [ prefixes = [
"VERSION", "VERSION",
"VER.", "VER.",
@ -124,17 +125,29 @@ def compareElements(s1, s2):
return 1 return 1
else: else:
return 2 return 2
# if the strings aren't numeric or start from 0, compare them as a strings: # if the strings aren't numeric or start from 0, compare them as a strings:
# but first, set ALPHA < BETA < PREVIEW < RC < TRUNK < [NOTHING] < [ANYTHING_ELSE] # but first, set ALPHA < BETA < PREVIEW < RC < TRUNK < [NOTHING] < [ANYTHING_ELSE] < POST < DEV
if s1 not in ["A", "ALPHA", "B", "BETA", "PREVIEW", "RC", "TRUNK"]: pre = ["A", "ALPHA", "B", "BETA", "PREV", "PREVIEW", "RC", "TRUNK"]
s1 = "Z" + s1 post = ["POST", "DEV"]
if s2 not in ["A", "ALPHA", "B", "BETA", "PREVIEW", "RC", "TRUNK"]:
s2 = "Z" + s2 if s1 in pre: # make it inferior to anything
s1 = chr(0) + str(pre.index(s1.replace("ALPHA", "A").replace("BETA", "B")))
elif s1 in post: # make it posterior to anything
s1 = chr(0x10FFFF) + str(post.index(s1))
if s2 in pre: # make it inferior to anything
s2 = chr(0) + str(pre.index(s2.replace("ALPHA", "A").replace("BETA", "B")))
elif s2 in post: # make it posterior to anything
s2 = chr(0x10FFFF) + str(post.index(s2))
# the final test: # the final test:
if s1 > s2: if s1 > s2:
return 1 return 1
else: elif s1 < s2:
return 2 return 2
else:
return 0
# ------------------------------------------------------------------------ # # ------------------------------------------------------------------------ #
@ -150,24 +163,23 @@ def compareVersions(a, b):
v1 = chopString(a) v1 = chopString(a)
v2 = chopString(b) v2 = chopString(b)
# set the shorter string as a base # set the shorter string as a base
l = len(v1) l1, l2 = len(v1), len(v2)
if l > len(v2): l = min(l1,l2)
l = len(v2)
# try to determine within the common length # try to determine within the common length
for i in range(l): for i in range(l):
if compareElements(v1[i], v2[i]): if return_code := compareElements(v1[i], v2[i]):
return compareElements(v1[i], v2[i]) return return_code
# if the lists are identical till the end of the shorter string, try to compare the odd tail # if the lists are identical till the end of the shorter string, try to compare the odd tail
# with the simple space (because the 'alpha', 'beta', 'preview' and 'rc' are LESS then nothing) # element-wise padding with "0"
if len(v1) > l: if l1 > l:
return compareElements(v1[l], " ") for i in range(l, l1):
if len(v2) > l: if return_code := compareElements(v1[i], "0"):
return compareElements(" ", v2[l]) return return_code
# if everything else fails... elif l2 > l:
if a > b: for i in range(l, l2):
return 1 if return_code := compareElements("0", v2[i]):
else: return return_code
return 2 return 0
""" """

View File

@ -105,9 +105,11 @@ class TestVersionCompare(QgisTestCase):
b = "1.0.0post1" b = "1.0.0post1"
self.assertEqual(compareVersions(a, b), 2) self.assertEqual(compareVersions(a, b), 2)
a = "1.0a1" # FIXME: these one will fail ...
b = "1.0.0alpha1" # should we use packaging.version.parse ?
self.assertEqual(compareVersions(a, b), 0) # a = "1.0a1"
# b = "1.0.0alpha1"
# self.assertEqual(compareVersions(a, b), 0)
if __name__ == "__main__": if __name__ == "__main__":