diff --git a/plugins/python-build/scripts/add_cpython.py b/plugins/python-build/scripts/add_cpython.py index 0742dd7a..51380e82 100755 --- a/plugins/python-build/scripts/add_cpython.py +++ b/plugins/python-build/scripts/add_cpython.py @@ -86,7 +86,12 @@ def adapt_script(version: packaging.version.Version, elif m:=re.match(r'\s*install_package\s+"(?Popenssl-\S+)"\s+' r'"(?P\S+)"\s.*$', line): - item = VersionDirectory.openssl.get_store_latest_release() + existing_version_str = m.group('package').split('-')[1] + if existing_version_str.startswith('1.1.1'): + prefix = '1.1.1' + else: + prefix = '.'.join(existing_version_str.split('.')[:2]) + item = VersionDirectory.openssl.get_store_latest_release(prefix) line = Re.sub_groups(m, package=item.package_name, @@ -129,6 +134,18 @@ def add_version(version: packaging.version.Version): return False VersionDirectory.existing.append(_CPythonExistingScriptInfo(version,str(new_path))) + if previous_version.major == version.major and previous_version.minor == version.minor: + import shutil + prev_patches = OUT_DIR / "patches" / str(previous_version) + new_patches = OUT_DIR / "patches" / str(version) + if prev_patches.exists() and not new_patches.exists(): + if is_prerelease_upgrade: + logger.info(f"Git moving patches from {previous_version} to {version}") + subprocess.check_call(("git", "-C", OUT_DIR, "mv", f"patches/{previous_version}", f"patches/{version}")) + else: + logger.info(f"Copying patches from {previous_version} to {version}") + shutil.copytree(prev_patches, new_patches) + cleanup_prerelease_upgrade(is_prerelease_upgrade, previous_version, version) handle_t_thunks(version, previous_version, is_prerelease_upgrade) @@ -211,7 +228,24 @@ def main(): VersionDirectory.available.get_store_available_source_downloads(release, True) del release - versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys()) + import subprocess + pending_versions = set() + try: + ls_remote = subprocess.check_output( + ["git", "-C", OUT_DIR, "ls-remote", "origin", "refs/heads/auto_add_version/*"], + text=True + ) + for line in ls_remote.splitlines(): + branch = line.split("\t")[1].replace("refs/heads/auto_add_version/", "") + for v_str in branch.split("_"): + try: + pending_versions.add(packaging.version.Version(v_str)) + except ValueError: + pass + except Exception as e: + logger.warning(f"Failed to fetch pending PR branches: {e}") + + versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys() - pending_versions) logger.info("Versions to add:\n"+pprint.pformat(versions_to_add)) result = False @@ -440,18 +474,30 @@ class _OpenSSLVersionInfo(typing.NamedTuple): class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.Version]): key_field = "version" - def get_store_latest_release(self) \ + def get_store_latest_release(self, prefix=None) \ -> _OpenSSLVersionInfo: - if self: + if prefix: + matching = [v for v in self.values() if str(v.version).startswith(prefix)] + if matching: + return max(matching, key=lambda v: v.version) + elif self: #already retrieved return self[max(self.keys())] - j = requests.get("https://api.github.com/repos/openssl/openssl/releases/latest", timeout=30).json() + j = requests.get("https://api.github.com/repos/openssl/openssl/releases", timeout=30).json() + releases = [r for r in j if not r.get('prerelease')] + if prefix: + releases_prefix = [r for r in releases if r.get('tag_name', '').startswith(f"openssl-{prefix}")] + if releases_prefix: + releases = releases_prefix + + j_release = releases[0] + # noinspection PyTypeChecker # urlparse can parse str as well as bytes shasum_url = more_itertools.one( asset['browser_download_url'] - for asset in j['assets'] + for asset in j_release['assets'] if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1].endswith('.sha256') ) shasum_text = requests.get(shasum_url, timeout=30).text @@ -467,7 +513,7 @@ class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version. package_url = more_itertools.one( asset['browser_download_url'] - for asset in j['assets'] + for asset in j_release['assets'] if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1] == package_filename )