xref: /aosp_15_r20/external/bazelbuild-rules_python/python/private/local_runtime_toolchains_repo.bzl (revision 60517a1edbc8ecf509223e9af94a7adec7d736b8)
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"""Create a repository to hold a local Python toolchain definitions."""
16
17load("//python/private:text_util.bzl", "render")
18load(":repo_utils.bzl", "REPO_DEBUG_ENV_VAR", "repo_utils")
19
20_TOOLCHAIN_TEMPLATE = """
21# Generated by local_runtime_toolchains_repo.bzl
22
23load("@rules_python//python/private:py_toolchain_suite.bzl", "define_local_toolchain_suites")
24
25define_local_toolchain_suites(
26    name = "toolchains",
27    version_aware_repo_names = {version_aware_names},
28    version_unaware_repo_names = {version_unaware_names},
29)
30"""
31
32def _local_runtime_toolchains_repo(rctx):
33    logger = repo_utils.logger(rctx)
34    rctx.file("WORKSPACE", "")
35    rctx.file("MODULE.bazel", "")
36    rctx.file("REPO.bazel", "")
37
38    logger.info(lambda: _format_toolchains_for_logging(rctx))
39
40    rctx.file("BUILD.bazel", _TOOLCHAIN_TEMPLATE.format(
41        version_aware_names = render.list(rctx.attr.runtimes),
42        version_unaware_names = render.list(rctx.attr.default_runtimes or rctx.attr.runtimes),
43    ))
44
45local_runtime_toolchains_repo = repository_rule(
46    implementation = _local_runtime_toolchains_repo,
47    doc = """
48Create a repo of toolchains definitions for local runtimes.
49
50This is intended to be used on the toolchain implemenations generated by
51`local_runtime_repo`.
52
53NOTE: This does not call `native.register_toolchains` -- the caller is
54responsible for registering the toolchains this defines.
55""",
56    attrs = {
57        "default_runtimes": attr.string_list(
58            doc = """
59The repo names of `local_runtime_repo` repos to define as toolchains.
60
61These will be defined as *version-unaware* toolchains. This means they will
62match any Python version. As such, they are registered after the version-aware
63toolchains defined by the `runtimes` attribute.
64
65Note that order matters: it determines the toolchain priority within the
66package.
67""",
68        ),
69        "runtimes": attr.string_list(
70            doc = """
71The repo names of `local_runtime_repo` repos to define as toolchains.
72
73These will be defined as *version-aware* toolchains. This means they require the
74`--//python/config_settings:python_version` to be set in order to match. These
75are registered before `default_runtimes`.
76
77Note that order matters: it determines the toolchain priority within the
78package.
79""",
80        ),
81        "_rule_name": attr.string(default = "local_toolchains_repo"),
82    },
83    environ = [REPO_DEBUG_ENV_VAR],
84)
85
86def _format_toolchains_for_logging(rctx):
87    lines = ["Local toolchain priority order:"]
88    i = 0
89    for i, name in enumerate(rctx.attr.runtimes, start = i):
90        lines.append("  {}: {} (version aware)".format(i, name))
91    for i, name in enumerate(rctx.attr.default_runtimes, start = i):
92        lines.append("  {}: {} (version unaware)".format(i, name))
93    return "\n".join(lines)
94