xref: /aosp_15_r20/external/bazelbuild-rules_python/python/uv/repositories.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"""
16EXPERIMENTAL: This is experimental and may be removed without notice
17
18Create repositories for uv toolchain dependencies
19"""
20
21load("//python/uv/private:toolchain_types.bzl", "UV_TOOLCHAIN_TYPE")
22load("//python/uv/private:toolchains_repo.bzl", "uv_toolchains_repo")
23load("//python/uv/private:versions.bzl", "UV_PLATFORMS", "UV_TOOL_VERSIONS")
24
25UV_BUILD_TMPL = """\
26# Generated by repositories.bzl
27load("@rules_python//python/uv:toolchain.bzl", "uv_toolchain")
28
29uv_toolchain(
30    name = "uv_toolchain",
31    uv = "{binary}",
32    version = "{version}",
33)
34"""
35
36def _uv_repo_impl(repository_ctx):
37    platform = repository_ctx.attr.platform
38    uv_version = repository_ctx.attr.uv_version
39
40    is_windows = "windows" in platform
41
42    suffix = ".zip" if is_windows else ".tar.gz"
43    filename = "uv-{platform}{suffix}".format(
44        platform = platform,
45        suffix = suffix,
46    )
47    url = "https://github.com/astral-sh/uv/releases/download/{version}/{filename}".format(
48        version = uv_version,
49        filename = filename,
50    )
51    if filename.endswith(".tar.gz"):
52        strip_prefix = filename[:-len(".tar.gz")]
53    else:
54        strip_prefix = ""
55
56    repository_ctx.download_and_extract(
57        url = url,
58        sha256 = UV_TOOL_VERSIONS[repository_ctx.attr.uv_version][repository_ctx.attr.platform].sha256,
59        stripPrefix = strip_prefix,
60    )
61
62    binary = "uv.exe" if is_windows else "uv"
63    repository_ctx.file(
64        "BUILD.bazel",
65        UV_BUILD_TMPL.format(
66            binary = binary,
67            version = uv_version,
68        ),
69    )
70
71uv_repository = repository_rule(
72    _uv_repo_impl,
73    doc = "Fetch external tools needed for uv toolchain",
74    attrs = {
75        "platform": attr.string(mandatory = True, values = UV_PLATFORMS.keys()),
76        "uv_version": attr.string(mandatory = True, values = UV_TOOL_VERSIONS.keys()),
77    },
78)
79
80# buildifier: disable=unnamed-macro
81def uv_register_toolchains(uv_version = None, register_toolchains = True):
82    """Convenience macro which does typical toolchain setup
83
84    Skip this macro if you need more control over the toolchain setup.
85
86    Args:
87        uv_version: The uv toolchain version to download.
88        register_toolchains: If true, repositories will be generated to produce and register `uv_toolchain` targets.
89    """
90    if not uv_version:
91        fail("uv_version is required")
92
93    toolchain_names = []
94    toolchain_labels_by_toolchain = {}
95    toolchain_compatible_with_by_toolchain = {}
96
97    for platform in UV_PLATFORMS.keys():
98        uv_repository_name = UV_PLATFORMS[platform].default_repo_name
99
100        uv_repository(
101            name = uv_repository_name,
102            uv_version = uv_version,
103            platform = platform,
104        )
105
106        toolchain_name = uv_repository_name + "_toolchain"
107        toolchain_names.append(toolchain_name)
108        toolchain_labels_by_toolchain[toolchain_name] = "@{}//:uv_toolchain".format(uv_repository_name)
109        toolchain_compatible_with_by_toolchain[toolchain_name] = UV_PLATFORMS[platform].compatible_with
110
111    uv_toolchains_repo(
112        name = "uv_toolchains",
113        toolchain_type = str(UV_TOOLCHAIN_TYPE),
114        toolchain_names = toolchain_names,
115        toolchain_labels = toolchain_labels_by_toolchain,
116        toolchain_compatible_with = toolchain_compatible_with_by_toolchain,
117    )
118
119    if register_toolchains:
120        native.register_toolchains("@uv_toolchains//:all")
121