From cdfb371ea9d8615b83e3cb50bb4e68b75e091b8a Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Fri, 3 Feb 2023 23:07:58 +0900 Subject: [PATCH] Attempt to fix issues with packaging.version.parse Defined a new class "ArchPkgVersion" to handle versions. May replace usage of `packaging.version.parse(...)`. --- update.py | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/update.py b/update.py index 1456fdf..d1d5be7 100755 --- 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( -- 2.49.0