]> git.seodisparate.com - AnotherAURHelper/commitdiff
Attempt to fix issues with packaging.version.parse
authorStephen Seo <seo.disparate@gmail.com>
Fri, 3 Feb 2023 14:07:58 +0000 (23:07 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Fri, 3 Feb 2023 14:07:58 +0000 (23:07 +0900)
Defined a new class "ArchPkgVersion" to handle versions. May replace
usage of `packaging.version.parse(...)`.

update.py

index 1456fdfeb6724895a583951590a7692a7e41ca31..d1d5be7df4bab29df1714b07797660491a168ae8 100755 (executable)
--- a/update.py
+++ b/update.py
@@ -24,6 +24,172 @@ AUR_GIT_REPO_PATH = "https://aur.archlinux.org"
 AUR_GIT_REPO_PATH_TEMPLATE = AUR_GIT_REPO_PATH + "/{}.git"
 GLOBAL_LOG_FILE = "log.txt"
 DEFAULT_EDITOR = "/usr/bin/nano"
+ENDS_WITH_DIGIT_REGEX = re.compile("^(.*?)([0-9]+)$")
+
+
+class ArchPkgVersion():
+    def __init__(self, version_str):
+        self.versions = []
+        self.pkgver = 0
+        end_dash_idx = version_str.rfind('-')
+        if end_dash_idx != -1:
+            try:
+                self.pkgver = int(version_str[end_dash_idx+1:])
+            except ValueError:
+                self.pkgver = version_str[end_dash_idx+1:]
+            version_str = version_str[:end_dash_idx]
+
+        for sub in version_str.split('.'):
+            try:
+                integer = int(sub)
+                self.versions.append(integer)
+            except ValueError:
+                match = ENDS_WITH_DIGIT_REGEX.match(sub)
+                if match is not None:
+                    subversion = []
+                    subversion.append(match.groups()[0])
+                    subversion.append(int(match.groups()[1]))
+                    self.versions.append(tuple(subversion))
+                else:
+                    self.versions.append(sub)
+
+    def compare_with(self, other_self):
+        self_count = len(self.versions)
+        other_count = len(other_self.versions)
+        if other_count < self_count:
+            count = other_count
+        else:
+            count = self_count
+        for i in range(count):
+            if type(self.versions[i]) is tuple:
+                if type(other_self.versions[i]) is tuple:
+                    self_subcount = len(self.versions[i])
+                    other_subcount = len(other_self.versions[i])
+                    if other_subcount < self_subcount:
+                        subcount = other_subcount
+                    else:
+                        subcount = self_subcount
+                    for j in range(subcount):
+                        try:
+                            if self.versions[i][j] < other_self.versions[i][j]:
+                                return -1
+                            elif self.versions[i][j] > other_self.versions[i][j]:
+                                return 1
+                        except TypeError:
+                            if str(self.versions[i][j]) < str(other_self.versions[i][j]):
+                                return -1
+                            elif str(self.versions[i][j]) > str(other_self.versions[i][j]):
+                                return 1
+                    if self_subcount < other_subcount:
+                        return -1
+                    elif self_subcount > other_subcount:
+                        return 1
+                else:
+                    # self is tuple but other is not
+                    return 1
+            elif type(other_self.versions[i]) is tuple:
+                # other is tuple but self is not
+                return -1
+            else:
+                try:
+                    if self.versions[i] < other_self.versions[i]:
+                        return -1
+                    elif self.versions[i] > other_self.versions[i]:
+                        return 1
+                except TypeError:
+                    if str(self.versions[i]) < str(other_self.versions[i]):
+                        return -1
+                    elif str(self.versions[i]) > str(other_self.versions[i]):
+                        return 1
+        if self_count < other_count:
+            return -1
+        elif self_count > other_count:
+            return 1
+        else:
+            try:
+                if self.pkgver < other_self.pkgver:
+                    return -1
+                elif self.pkgver > other_self.pkgver:
+                    return 1
+                else:
+                    return 0
+            except TypeError:
+                if str(self.pkgver) < str(other_self.pkgver):
+                    return -1
+                elif str(self.pkgver) > str(other_self.pkgver):
+                    return 1
+                else:
+                    return 0
+
+
+    def __eq__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            return self.compare_with(other) == 0
+        else:
+            return False
+
+    def __ne__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            return self.compare_with(other) != 0
+        else:
+            return False
+
+    def __lt__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            return self.compare_with(other) < 0
+        else:
+            return False
+
+    def __le__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            result = self.compare_with(other)
+            return result <= 0
+        else:
+            return False
+
+    def __gt__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            return self.compare_with(other) > 0
+        else:
+            return False
+
+    def __ge__(self, other):
+        if isinstance(other, version.Version):
+            other = ArchPkgVersion(str(other))
+
+        if isinstance(other, ArchPkgVersion):
+            result = self.compare_with(other)
+            return result >= 0
+        else:
+            return False
+
+    def __str__(self):
+        self_str = ""
+        for idx in range(len(self.versions)):
+            if type(self.versions[idx]) is tuple:
+                for sub in self.versions[idx]:
+                    self_str += str(sub)
+            else:
+                self_str += str(self.versions[idx])
+            if idx + 1 < len(self.versions):
+                self_str += '.'
+        self_str += "-" + str(self.pkgver)
+        return self_str
 
 
 def log_print(*args, **kwargs):
@@ -506,6 +672,15 @@ def get_pkgbuild_version(
         return False, None, None, None
 
 
+def version_parse_checked(version_str: str):
+    try:
+        return version.parse(version_str)
+    except version.InvalidVersion:
+        self_version = ArchPkgVersion(version_str)
+        log_print(f'WARNING: version.parse(\"{version_str}\") failed to parse! Defaulting to self-defined version \"{self_version}\".')
+        return self_version
+
+
 def get_srcinfo_check_result(
     current_epoch: Union[str, None],
     current_version: str,
@@ -554,8 +729,8 @@ def get_srcinfo_check_result(
         elif (
             pkgver is not None
             and pkgrel is not None
-            and version.parse(current_version)
-            < version.parse(pkgver + "-" + pkgrel)
+            and version_parse_checked(current_version)
+            < version_parse_checked(pkgver + "-" + pkgrel)
         ):
             log_print(
                 'Current installed version of "{}" is out of date (older version).'.format(