| """Rule for generating an execution-phase action failure when a PyPI package is missing.""" |
| |
| load("//python/private:py_info.bzl", "PyInfo") |
| load("//python/private:reexports.bzl", "BuiltinPyInfo") |
| |
| def _missing_package_error_impl(ctx): |
| out = ctx.actions.declare_file(ctx.label.name + ".error") |
| |
| if ctx.attr.hub_name: |
| hub_clause = ' when building under PyPI hub "{hub}". Try adding it to the requirements of this hub (e.g. requirements_lock or requirements_by_platform in pip.parse)'.format( |
| hub = ctx.attr.hub_name, |
| ) |
| else: |
| hub_clause = ' because no default PyPI hub was configured. Try designating a default hub via pip.default(default_hub = "...") or select a hub using --@rules_python//python/config_settings:venv' |
| |
| # Register an action that fails when Bazel attempts to stage/build this file |
| ctx.actions.run_shell( |
| outputs = [out], |
| command = "echo 'ERROR: PyPI package \"{pkg}\" is not available{hub_clause}.' >&2 && exit 1".format( |
| pkg = ctx.attr.package_name, |
| hub_clause = hub_clause, |
| ), |
| ) |
| |
| maybe_builtin = [BuiltinPyInfo(transitive_sources = depset([out]))] if BuiltinPyInfo != None else [] |
| |
| return [ |
| DefaultInfo( |
| files = depset([out]), |
| data_runfiles = ctx.runfiles([out]), |
| ), |
| PyInfo( |
| transitive_sources = depset([out]), |
| ), |
| ] + maybe_builtin |
| |
| missing_package_error = rule( |
| implementation = _missing_package_error_impl, |
| attrs = { |
| "hub_name": attr.string(mandatory = True), |
| "package_name": attr.string(mandatory = True), |
| }, |
| ) |