Skip to content
File

Blob: build/deps/formatters/rustfmt_repository.bzl

3.8 KB
1"""
2Repository rule that downloads a standalone rustfmt binary along with the rustc
3shared libraries it depends on.
4 
5This avoids needing `bazel run @rules_rust//:rustfmt`, which triggers C++ toolchain
6resolution and (in edgeworker) the V8 build cache download — a multi-GB fetch that
7is unnecessary for code formatting.
8"""
9 
10load("@@//:build/http_proxy_config.bzl", "PROXY_URL")
11 
12_URL_TEMPLATE = "https://static.rust-lang.org/dist/{iso_date}/{component}-nightly-{triple}.tar.xz"
13 
14def _rustfmt_standalone_repository_impl(repository_ctx):
15 triple = repository_ctx.attr.triple
16 iso_date = repository_ctx.attr.iso_date
17 proxy = PROXY_URL
18 
19 # Download the rustfmt component (contains bin/rustfmt and bin/cargo-fmt).
20 rustfmt_url = proxy + _URL_TEMPLATE.format(
21 iso_date = iso_date,
22 component = "rustfmt",
23 triple = triple,
24 )
25 repository_ctx.download_and_extract(
26 url = rustfmt_url,
27 sha256 = repository_ctx.attr.rustfmt_sha256,
28 stripPrefix = "rustfmt-nightly-{}/rustfmt-preview".format(triple),
29 )
30 
31 # Download the rustc component (contains shared libraries that rustfmt
32 # dynamically links against, e.g. librustc_driver-*.so / .dylib).
33 rustc_url = proxy + _URL_TEMPLATE.format(
34 iso_date = iso_date,
35 component = "rustc",
36 triple = triple,
37 )
38 repository_ctx.download_and_extract(
39 url = rustc_url,
40 sha256 = repository_ctx.attr.rustc_sha256,
41 stripPrefix = "rustc-nightly-{}/rustc".format(triple),
42 )
43 
44 # Create a wrapper script that sets the library path so the dynamically-linked
45 # rustfmt binary can find its libraries. We embed absolute paths because the
46 # wrapper may be copied to bazel-bin by native_binary.
47 repo_dir = str(repository_ctx.path(""))
48 is_macos = "apple-darwin" in triple
49 if is_macos:
50 wrapper = """\
51#!/bin/bash
52DYLD_LIBRARY_PATH="{lib_dir}:${{DYLD_LIBRARY_PATH:-}}" exec "{rustfmt_bin}" "$@"
53"""
54 else:
55 wrapper = """\
56#!/bin/bash
57LD_LIBRARY_PATH="{lib_dir}:${{LD_LIBRARY_PATH:-}}" exec "{rustfmt_bin}" "$@"
58"""
59 repository_ctx.file("rustfmt", content = wrapper.format(
60 lib_dir = repo_dir + "/lib",
61 rustfmt_bin = repo_dir + "/bin/rustfmt",
62 ), executable = True)
63 
64 repository_ctx.file("BUILD.bazel", 'exports_files(["rustfmt"])\n')
65 
66rustfmt_standalone_repository = repository_rule(
67 doc = "Downloads a standalone rustfmt binary and the rustc shared libraries it needs.",
68 attrs = {
69 "triple": attr.string(mandatory = True, doc = "Rust target triple, e.g. x86_64-unknown-linux-gnu"),
70 "iso_date": attr.string(mandatory = True, doc = "Nightly date, e.g. 2026-02-12"),
71 "rustfmt_sha256": attr.string(mandatory = True, doc = "SHA-256 of the rustfmt component tarball"),
72 "rustc_sha256": attr.string(mandatory = True, doc = "SHA-256 of the rustc component tarball"),
73 },
74 implementation = _rustfmt_standalone_repository_impl,
75)
76 
77# -- Module extension --
78 
79def _rustfmt_standalone_ext_impl(module_ctx):
80 for mod in module_ctx.modules:
81 for repo in mod.tags.repo:
82 rustfmt_standalone_repository(
83 name = repo.name,
84 triple = repo.triple,
85 iso_date = repo.iso_date,
86 rustfmt_sha256 = repo.rustfmt_sha256,
87 rustc_sha256 = repo.rustc_sha256,
88 )
89 return module_ctx.extension_metadata(
90 root_module_direct_deps = "all",
91 root_module_direct_dev_deps = [],
92 )
93 
94_repo_tag = tag_class(attrs = {
95 "name": attr.string(mandatory = True),
96 "triple": attr.string(mandatory = True),
97 "iso_date": attr.string(mandatory = True),
98 "rustfmt_sha256": attr.string(mandatory = True),
99 "rustc_sha256": attr.string(mandatory = True),
100})
101 
102rustfmt_standalone = module_extension(
103 implementation = _rustfmt_standalone_ext_impl,
104 tag_classes = {"repo": _repo_tag},
105)