1# Copyright 2024 The Bazel Authors. All rights reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""whl_library aliases for multi_pip_parse.""" 16 17load("//python/private:full_version.bzl", "full_version") 18load(":render_pkg_aliases.bzl", "NO_MATCH_ERROR_MESSAGE_TEMPLATE") 19 20def _whl_library_alias_impl(rctx): 21 rules_python = rctx.attr._rules_python_workspace.workspace_name 22 if rctx.attr.default_version: 23 default_repo_prefix = rctx.attr.version_map[rctx.attr.default_version] 24 else: 25 default_repo_prefix = None 26 version_map = rctx.attr.version_map.items() 27 build_content = ["# Generated by python/pip.bzl"] 28 for alias_name in ["pkg", "whl", "data", "dist_info"]: 29 build_content.append(_whl_library_render_alias_target( 30 alias_name = alias_name, 31 default_repo_prefix = default_repo_prefix, 32 minor_mapping = rctx.attr.minor_mapping, 33 rules_python = rules_python, 34 version_map = version_map, 35 wheel_name = rctx.attr.wheel_name, 36 )) 37 rctx.file("BUILD.bazel", "\n".join(build_content)) 38 39def _whl_library_render_alias_target( 40 *, 41 alias_name, 42 default_repo_prefix, 43 minor_mapping, 44 rules_python, 45 version_map, 46 wheel_name): 47 alias = ["""\ 48alias( 49 name = "{alias_name}", 50 actual = select({{""".format(alias_name = alias_name)] 51 for [python_version, repo_prefix] in version_map: 52 alias.append("""\ 53 "@{rules_python}//python/config_settings:is_python_{full_python_version}": "{actual}",""".format( 54 full_python_version = full_version(version = python_version, minor_mapping = minor_mapping), 55 actual = "@{repo_prefix}{wheel_name}//:{alias_name}".format( 56 repo_prefix = repo_prefix, 57 wheel_name = wheel_name, 58 alias_name = alias_name, 59 ), 60 rules_python = rules_python, 61 )) 62 if default_repo_prefix: 63 default_actual = "@{repo_prefix}{wheel_name}//:{alias_name}".format( 64 repo_prefix = default_repo_prefix, 65 wheel_name = wheel_name, 66 alias_name = alias_name, 67 ) 68 alias.append(' "//conditions:default": "{default_actual}",'.format( 69 default_actual = default_actual, 70 )) 71 72 alias.append(" },") # Close select expression condition dict 73 if not default_repo_prefix: 74 supported_versions = sorted([python_version for python_version, _ in version_map]) 75 alias.append(' no_match_error="""{}""",'.format( 76 NO_MATCH_ERROR_MESSAGE_TEMPLATE.format( 77 supported_versions = ", ".join(supported_versions), 78 rules_python = rules_python, 79 ), 80 )) 81 alias.append(" ),") # Close the select expression 82 alias.append(' visibility = ["//visibility:public"],') 83 alias.append(")") # Close the alias() expression 84 return "\n".join(alias) 85 86whl_library_alias = repository_rule( 87 _whl_library_alias_impl, 88 attrs = { 89 "default_version": attr.string( 90 mandatory = False, 91 doc = "Optional Python version in major.minor format, e.g. '3.10'." + 92 "The Python version of the wheel to use when the versions " + 93 "from `version_map` don't match. This allows the default " + 94 "(version unaware) rules to match and select a wheel. If " + 95 "not specified, then the default rules won't be able to " + 96 "resolve a wheel and an error will occur.", 97 ), 98 "minor_mapping": attr.string_dict(mandatory = True), 99 "version_map": attr.string_dict(mandatory = True), 100 "wheel_name": attr.string(mandatory = True), 101 "_rules_python_workspace": attr.label(default = Label("//:WORKSPACE")), 102 }, 103) 104