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