| "" |
| |
| load("//python/private:auth.bzl", "AUTH_ATTRS", "get_auth") |
| load("//python/private:repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils") |
| load(":attrs.bzl", "ATTRS") |
| load(":patch_and_extract_whl.bzl", "patch_and_extract_whl") |
| load(":urllib.bzl", "urllib") |
| load(":whl_deps_repo.bzl", "whl_deps_attrs") |
| |
| def _whl_archive_impl(rctx): |
| logger = repo_utils.logger(rctx) |
| |
| whl_path = None |
| if rctx.attr.whl_file: |
| rctx.watch(rctx.attr.whl_file) |
| whl_path = rctx.path(rctx.attr.whl_file) |
| |
| # Simulate the behaviour where the whl is present in the current directory. |
| rctx.symlink(whl_path, whl_path.basename) |
| whl_path = rctx.path(whl_path.basename) |
| elif rctx.attr.urls and rctx.attr.filename: |
| filename = rctx.attr.filename |
| urls = rctx.attr.urls |
| urls = [ |
| urllib.absolute_url( |
| rctx.attr.index_url, |
| url, |
| envsubst = rctx.attr.envsubst, |
| getenv = rctx.getenv, |
| ) |
| for url in urls |
| ] |
| result = rctx.download( |
| url = urls, |
| output = filename, |
| sha256 = rctx.attr.sha256, |
| integrity = rctx.attr.integrity if not rctx.attr.sha256 else "", |
| auth = get_auth(rctx, urls), |
| ) |
| if not rctx.attr.sha256 and not rctx.attr.integrity: |
| # this is only seen when there is a direct URL reference without a hash |
| logger.warn("Please update the requirement line to include the hash:\n{} \\\n --hash=sha256:{}".format( |
| rctx.attr.requirement, |
| result.sha256, |
| )) |
| |
| if not result.success: |
| fail("could not download the '{}' from {}:\n{}".format(filename, urls, result)) |
| |
| if filename.endswith(".whl"): |
| whl_path = rctx.path(filename) |
| else: |
| fail("Only wheels are supported") |
| else: |
| fail("Either 'whl_file' or 'urls' and 'filename' needs to be specified") |
| |
| return patch_and_extract_whl(rctx, whl_path = whl_path, logger = logger) |
| |
| whl_archive_attrs = whl_deps_attrs | { |
| "annotation": attr.label( |
| doc = ( |
| "Optional json encoded file containing annotation to apply to the extracted wheel. " + |
| "See `package_annotation`" |
| ), |
| allow_files = True, |
| ), |
| "filename": attr.string( |
| doc = "Download the whl file to this filename. Only used when the `urls` is passed. If not specified, will be auto-detected from the `urls`.", |
| ), |
| "index_url": attr.string( |
| doc = "The index_url that the package will be downloaded from.", |
| ), |
| "integrity": attr.string( |
| doc = """\ |
| The expected checksum of the downloaded whl in Subresource Integrity format |
| (e.g. `sha256-...` or `sha512-...`). Only used when `urls` is passed. If |
| `sha256` is also set, it takes precedence over this attribute. |
| |
| :::{versionadded} 2.3.0 |
| ::: |
| """, |
| ), |
| "sha256": attr.string( |
| doc = "The sha256 of the downloaded whl. Only used when the `urls` is passed.", |
| ), |
| "urls": attr.string_list( |
| doc = """\ |
| The list of urls of the whl to be downloaded using bazel downloader. Using this |
| attr makes `extra_pip_args` and `download_only` ignored.""", |
| ), |
| # attributes only relevant to this rule and not reusable outside |
| "whl_file": attr.label( |
| doc = "The whl file that should be used instead of downloading or building the whl.", |
| ), |
| "whl_patches": attr.label_keyed_string_dict( |
| doc = """ |
| A label-keyed-string dict with patch files as keys and json-strings as values. |
| |
| The keys are labels to the patch file to apply. |
| |
| The values describe what to apply the patch to and how to apply it. |
| It is encoded as `json.encode(struct([whls], patch_strip])`, |
| where `whls` is a `list[str`] of wheel filenames, and `patch_strip` |
| is a number. |
| |
| So it will look something like this: |
| ``` |
| "//path/to/package:my.patch": json.encode(struct( |
| whls = ["something-2.7.1-py3-none-any.whl"], |
| patch_strip = 1, |
| )), |
| ``` |
| The patch is applied within the scope of the .whl file. |
| I.e. you should create the patch from the same place you unziped the wheel. |
| |
| |
| This is to maintain flexibility and correct bzlmod extension interface until we have a better |
| way to define whl_library and move whl patching to a separate place. INTERNAL USE ONLY.""", |
| ), |
| } | { |
| k: ATTRS[k] |
| for k in [ |
| # legacy parameters that are global to the entire hub. |
| "enable_implicit_namespace_pkgs", |
| "envsubst", |
| "pip_data_exclude", |
| ] |
| } | AUTH_ATTRS |
| |
| whl_archive = repository_rule( |
| attrs = whl_archive_attrs | { |
| "_rule_name": attr.string(default = "whl_archive"), |
| }, |
| doc = """ |
| Download and extracts a single wheel based into a bazel repo based on the requirement string passed in. |
| |
| Does not depend on any python. |
| """, |
| implementation = _whl_archive_impl, |
| environ = [ |
| REPO_DEBUG_ENV_VAR, |
| ], |
| ) |