refactor(repo_utils): create a helper for extracting files (#3459)
This just moves common code to the same place, so that we can better
maintain extracting from the whls easier.
Work towards #2945
diff --git a/python/private/pypi/BUILD.bazel b/python/private/pypi/BUILD.bazel
index 7d5314d..dd86dcf 100644
--- a/python/private/pypi/BUILD.bazel
+++ b/python/private/pypi/BUILD.bazel
@@ -247,6 +247,7 @@
deps = [
":parse_whl_name_bzl",
"//python/private:repo_utils_bzl",
+ "@rules_python_internal//:rules_python_config_bzl",
],
)
diff --git a/python/private/pypi/patch_whl.bzl b/python/private/pypi/patch_whl.bzl
index e315989..71b46f6 100644
--- a/python/private/pypi/patch_whl.bzl
+++ b/python/private/pypi/patch_whl.bzl
@@ -27,6 +27,8 @@
within the wheel.
"""
+load("@rules_python_internal//:rules_python_config.bzl", rp_config = "config")
+load("//python/private:repo_utils.bzl", "repo_utils")
load(":parse_whl_name.bzl", "parse_whl_name")
load(":pypi_repo_utils.bzl", "pypi_repo_utils")
@@ -84,16 +86,11 @@
# does not support patching in another directory.
whl_input = rctx.path(whl_path)
- # symlink to a zip file to use bazel's extract so that we can use bazel's
- # repository_ctx patch implementation. The whl file may be in a different
- # external repository.
- #
- # TODO @aignas 2025-11-24: remove this symlinking workaround when we drop support for bazel 7
- whl_file_zip = whl_input.basename + ".zip"
- rctx.symlink(whl_input, whl_file_zip)
- rctx.extract(whl_file_zip)
- if not rctx.delete(whl_file_zip):
- fail("Failed to remove the symlink after extracting")
+ repo_utils.extract(
+ rctx,
+ archive = whl_input,
+ supports_whl_extraction = rp_config.supports_whl_extraction,
+ )
if not patches:
fail("Trying to patch wheel without any patches")
diff --git a/python/private/pypi/whl_library.bzl b/python/private/pypi/whl_library.bzl
index 044d18a..fdb3f93 100644
--- a/python/private/pypi/whl_library.bzl
+++ b/python/private/pypi/whl_library.bzl
@@ -377,17 +377,12 @@
#
# Remove non-pipstar and config_load check when we release rules_python 2.
if enable_pipstar:
- if rp_config.supports_whl_extraction:
- extract_path = whl_path
- else:
- extract_path = rctx.path(whl_path.basename + ".zip")
- rctx.symlink(whl_path, extract_path)
- rctx.extract(
- archive = extract_path,
+ repo_utils.extract(
+ rctx,
+ archive = whl_path,
output = "site-packages",
+ supports_whl_extraction = rp_config.supports_whl_extraction,
)
- if not rp_config.supports_whl_extraction:
- rctx.delete(extract_path)
metadata = whl_metadata(
install_dir = whl_path.dirname.get_child("site-packages"),
diff --git a/python/private/repo_utils.bzl b/python/private/repo_utils.bzl
index 77eac55..1abff36 100644
--- a/python/private/repo_utils.bzl
+++ b/python/private/repo_utils.bzl
@@ -429,11 +429,34 @@
return "riscv64"
return arch
+def _extract(mrctx, *, archive, supports_whl_extraction = False, **kwargs):
+ """Extract an archive
+
+ TODO: remove when the earliest supported bazel version is at least 8.3.
+
+ Note, we are using the parameter here because there is very little ways how we can detect
+ whether we can support just extracting the whl.
+ """
+ archive_original = None
+ if not supports_whl_extraction and archive.basename.endswith(".whl"):
+ archive_original = archive
+ archive = mrctx.path(archive.basename + ".zip")
+ mrctx.symlink(archive_original, archive)
+
+ mrctx.extract(
+ archive = archive,
+ **kwargs
+ )
+ if archive_original:
+ if not mrctx.delete(archive):
+ fail("Failed to remove the symlink after extracting")
+
repo_utils = struct(
# keep sorted
execute_checked = _execute_checked,
execute_checked_stdout = _execute_checked_stdout,
execute_unchecked = _execute_unchecked,
+ extract = _extract,
get_platforms_cpu_name = _get_platforms_cpu_name,
get_platforms_os_name = _get_platforms_os_name,
getenv = _getenv,