diff --git a/CHANGELOG.md b/CHANGELOG.md index edf01f798f..c87e76e5be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ A brief description of the categories of changes: * `3.12 -> 3.12.4` ### Fixed +* (rules) correctly handle absolute URLs in parse_simpleapi_html.bzl. * (rules) Fixes build targets linking against `@rules_python//python/cc:current_py_cc_libs` in host platform builds on macOS, by editing the `LC_ID_DYLIB` field of the hermetic interpreter's `libpython3.x.dylib` using `install_name_tool`, setting it to its absolute path under Bazel's diff --git a/python/private/pypi/parse_simpleapi_html.bzl b/python/private/pypi/parse_simpleapi_html.bzl index 248846922f..81ee385f86 100644 --- a/python/private/pypi/parse_simpleapi_html.bzl +++ b/python/private/pypi/parse_simpleapi_html.bzl @@ -96,7 +96,25 @@ def parse_simpleapi_html(*, url, content): whls = whls, ) +def _get_root_directory(url): + scheme_end = url.find("://") + if scheme_end == -1: + fail("Invalid URL format") + + scheme = url[:scheme_end] + host_end = url.find("/", scheme_end + 3) + if host_end == -1: + host_end = len(url) + host = url[scheme_end + 3:host_end] + + return "{}://{}".format(scheme, host) + def _absolute_url(index_url, candidate): + if candidate.startswith("/"): + # absolute url + root_directory = _get_root_directory(index_url) + return "{}{}".format(root_directory, candidate) + if not candidate.startswith(".."): return candidate diff --git a/python/private/pypi/simpleapi_download.bzl b/python/private/pypi/simpleapi_download.bzl index b258fef07a..c730c20439 100644 --- a/python/private/pypi/simpleapi_download.bzl +++ b/python/private/pypi/simpleapi_download.bzl @@ -185,10 +185,10 @@ def _read_simpleapi(ctx, url, attr, cache, **download_kwargs): if download_kwargs.get("block") == False: # Simulate the same API as ctx.download has return struct( - wait = lambda: _read_index_result(ctx, download.wait(), output, url, cache, cache_key), + wait = lambda: _read_index_result(ctx, download.wait(), output, real_url, cache, cache_key), ) - return _read_index_result(ctx, download, output, url, cache, cache_key) + return _read_index_result(ctx, download, output, real_url, cache, cache_key) def _read_index_result(ctx, result, output, url, cache, cache_key): if not result.success: diff --git a/tests/pypi/parse_simpleapi_html/parse_simpleapi_html_tests.bzl b/tests/pypi/parse_simpleapi_html/parse_simpleapi_html_tests.bzl index a532e878a7..aa735b83d8 100644 --- a/tests/pypi/parse_simpleapi_html/parse_simpleapi_html_tests.bzl +++ b/tests/pypi/parse_simpleapi_html/parse_simpleapi_html_tests.bzl @@ -221,6 +221,40 @@ def _test_whls(env): yanked = False, ), ), + ( + struct( + attrs = [ + 'href="/whl/torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl#sha256=deadbeef"', + ], + filename = "torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + url = "https://download.pytorch.org/whl/cpu/torch", + ), + struct( + filename = "torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + metadata_sha256 = "", + metadata_url = "", + sha256 = "deadbeef", + url = "https://download.pytorch.org/whl/torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + yanked = False, + ), + ), + ( + struct( + attrs = [ + 'href="/whl/torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl#sha256=notdeadbeef"', + ], + filename = "torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + url = "http://download.pytorch.org/whl/cpu/torch", + ), + struct( + filename = "torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + metadata_sha256 = "", + metadata_url = "", + sha256 = "notdeadbeef", + url = "http://download.pytorch.org/whl/torch-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", + yanked = False, + ), + ), ] for (input, want) in tests: