@@ -19,18 +19,14 @@ load("@bazel_tools//tools/build_defs/repo:utils.bzl", "update_attrs")
1919_TOOLCHAINS_REPO = "rules_buf_toolchains"
2020
2121_BUILD_FILE = """
22- load(":toolchain.bzl", "declare_buf_toolchains")
23-
2422package(default_visibility = ["//visibility:public"])
2523
26- declare_buf_toolchains(
27- os = "{os}",
28- cpu = "{cpu}",
29- rules_buf_repo_name = "{rules_buf_repo_name}",
30- )
24+ load(":toolchain.bzl", "implement_buf_toolchains")
25+
26+ implement_buf_toolchains("{cmd_suffix}")
3127"""
3228
33- _TOOLCHAIN_FILE = """
29+ _IMPLEMENT_TOOLCHAIN_FILE = """
3430def _buf_toolchain_impl(ctx):
3531 toolchain_info = platform_common.ToolchainInfo(
3632 cli = ctx.executable.cli,
@@ -50,51 +46,79 @@ _buf_toolchain = rule(
5046 },
5147)
5248
53- def declare_buf_toolchains(os, cpu, rules_buf_repo_name ):
49+ def implement_buf_toolchains(cmd_suffix ):
5450 for cmd in ["buf", "protoc-gen-buf-lint", "protoc-gen-buf-breaking"]:
55- cmd_suffix = ""
56- if os == "windows":
57- cmd_suffix = ".exe"
5851 toolchain_impl = cmd + "_toolchain_impl"
5952 _buf_toolchain(
6053 name = toolchain_impl,
6154 cli = str(Label("//:"+ cmd + cmd_suffix)),
6255 )
56+
57+ """
58+
59+ _DECLARE_TOOLCHAINS_HEAD = """
60+ def declare_buf_toolchains(rules_buf_repo_name):
61+ for cmd in ["buf", "protoc-gen-buf-lint", "protoc-gen-buf-breaking"]:
62+ toolchain_impl = cmd + "_toolchain_impl"
63+ """
64+
65+ _DECLARE_TOOLCHAINS_CALL = """
6366 native.toolchain(
64- name = cmd + "_toolchain",
65- toolchain = ":" + toolchain_impl,
66- toolchain_type = "@@{} //tools/{}:toolchain_type".format(rules_buf_repo_name, cmd),
67+ name = cmd + "_{os}_{arch} _toolchain",
68+ toolchain = "@@{name}_{os}_{arch}// :" + toolchain_impl,
69+ toolchain_type = "@@{{}} //tools/{{} }:toolchain_type".format(rules_buf_repo_name, cmd),
6770 exec_compatible_with = [
68- "@platforms//os:" + os ,
69- "@platforms//cpu:" + cpu,
71+ "@platforms//os:{os}" ,
72+ "@platforms//cpu:{ cpu}" ,
7073 ],
7174 )
75+ """
76+
77+ _DECLARE_TOOLCHAINS_BUILD_FILE = """
78+ package(default_visibility = ["//visibility:public"])
7279
80+ load(":toolchain.bzl", "declare_buf_toolchains")
81+
82+ declare_buf_toolchains(
83+ rules_buf_repo_name = "{rules_buf_repo_name}",
84+ )
7385"""
7486
75- def _register_toolchains (repo , cmd ):
87+ def _register_toolchains (repo ):
7688 native .register_toolchains (
77- "@{repo}//:{cmd}_toolchain " .format (
89+ "@{repo}//:all " .format (
7890 repo = repo ,
79- cmd = cmd ,
8091 ),
8192 )
8293
83- # Copied from rules_go: https://github.com/bazelbuild/rules_go/blob/19ad920c6869a179d186a365d117ab82f38d0f3a/go/private/sdk.bzl#L517
84- def _detect_host_platform (ctx ):
85- goos = ctx .os .name
86- if goos == "mac os x" :
87- goos = "darwin"
88- elif goos .startswith ("windows" ):
89- goos = "windows"
90-
91- goarch = ctx .os .arch
92- if goarch == "aarch64" :
93- goarch = "arm64"
94- elif goarch == "x86_64" :
95- goarch = "amd64"
96-
97- return goos , goarch
94+ def _buf_register_toolchains_impl (ctx ):
95+ platforms = ctx .attr .platforms # list of "{os}-{arch}" strings
96+ ctx .file (
97+ "BUILD" ,
98+ _DECLARE_TOOLCHAINS_BUILD_FILE .format (
99+ rules_buf_repo_name = Label ("//buf/repositories.bzl" ).workspace_name ,
100+ ),
101+ )
102+ toolchain_file_text = _DECLARE_TOOLCHAINS_HEAD
103+ for platform in platforms :
104+ os , arch = platform .split ("-" , 1 )
105+ if os == "darwin" :
106+ os = "osx"
107+ cpu = arch
108+ if cpu == "amd64" :
109+ cpu = "x86_64"
110+ toolchain_file_text += _DECLARE_TOOLCHAINS_CALL .format (name = ctx .attr .name , os = os , arch = arch , cpu = cpu )
111+ ctx .file ("toolchain.bzl" , toolchain_file_text )
112+
113+ buf_register_toolchains = repository_rule (
114+ implementation = _buf_register_toolchains_impl ,
115+ attrs = {
116+ "platforms" : attr .string_list (
117+ doc = "Buf platforms" ,
118+ mandatory = True ,
119+ ),
120+ },
121+ )
98122
99123def _buf_download_releases_impl (ctx ):
100124 version = ctx .attr .version
@@ -111,15 +135,14 @@ def _buf_download_releases_impl(ctx):
111135 version_data = ctx .read ("version.json" )
112136 version = json .decode (version_data )["name" ]
113137
114- os , cpu = _detect_host_platform (ctx )
115- if os not in ["linux" , "darwin" , "windows" ] or cpu not in ["arm64" , "amd64" ]:
116- fail ("Unsupported operating system or cpu architecture " )
138+ os = ctx .attr .os
139+ cpu = ctx .attr .arch
117140 if os == "linux" and cpu == "arm64" :
118141 cpu = "aarch64"
119142 if cpu == "amd64" :
120143 cpu = "x86_64"
121144
122- ctx .report_progress ("Downloading buf release hash" )
145+ ctx .report_progress ("Downloading buf release hash for {}-{}" . format ( os , cpu ) )
123146 url = "{}/{}/sha256.txt" .format (repository_url , version )
124147 sha256 = ctx .download (
125148 url = url ,
@@ -128,7 +151,7 @@ def _buf_download_releases_impl(ctx):
128151 output = "sha256.txt" ,
129152 ).sha256
130153 ctx .file ("WORKSPACE" , "workspace(name = \" {name}\" )" .format (name = ctx .name ))
131- ctx .file ("toolchain.bzl" , _TOOLCHAIN_FILE )
154+ ctx .file ("toolchain.bzl" , _IMPLEMENT_TOOLCHAIN_FILE )
132155 sha_list = ctx .read ("sha256.txt" ).splitlines ()
133156 for sha_line in sha_list :
134157 if sha_line .strip (" " ).endswith (".tar.gz" ):
@@ -153,22 +176,25 @@ def _buf_download_releases_impl(ctx):
153176 output = output ,
154177 )
155178
156- if os == "darwin" :
157- os = "osx"
158-
159179 ctx .file (
160180 "BUILD" ,
161- _BUILD_FILE .format (
162- os = os ,
163- cpu = cpu ,
164- rules_buf_repo_name = Label ("//buf/repositories.bzl" ).workspace_name ,
165- ),
181+ _BUILD_FILE .format (cmd_suffix = ".exe" if os == "windows" else "" ),
166182 )
167183 return update_attrs (ctx .attr , ["version" , "sha256" ], {"version" : version , "sha256" : sha256 })
168184
169185buf_download_releases = repository_rule (
170186 implementation = _buf_download_releases_impl ,
171187 attrs = {
188+ "os" : attr .string (
189+ doc = "Buf release os" ,
190+ mandatory = True ,
191+ values = ["linux" , "darwin" , "windows" ],
192+ ),
193+ "arch" : attr .string (
194+ doc = "Buf release cpu arch" ,
195+ mandatory = True ,
196+ values = ["arm64" , "amd64" ],
197+ ),
172198 "version" : attr .string (
173199 doc = "Buf release version" ,
174200 ),
@@ -193,8 +219,18 @@ def rules_buf_toolchains(name = _TOOLCHAINS_REPO, version = None, sha256 = None,
193219 repository_url: The repository url base used for downloads. Defaults to "https://github.com/bufbuild/buf/releases/download"
194220 """
195221
196- buf_download_releases (name = name , version = version , sha256 = sha256 , repository_url = repository_url )
197-
198- _register_toolchains (name , "buf" )
199- _register_toolchains (name , "protoc-gen-buf-breaking" )
200- _register_toolchains (name , "protoc-gen-buf-lint" )
222+ platforms_for_registration = []
223+ for platform in (
224+ struct (os = "linux" , arch = "arm64" ),
225+ struct (os = "linux" , arch = "amd64" ),
226+ struct (os = "darwin" , arch = "arm64" ),
227+ struct (os = "darwin" , arch = "amd64" ),
228+ struct (os = "windows" , arch = "arm64" ),
229+ struct (os = "windows" , arch = "amd64" ),
230+ ):
231+ name_with_platform = "{}_{}_{}" .format (name , platform .os , platform .arch )
232+ buf_download_releases (name = name_with_platform , os = platform .os , arch = platform .arch , version = version , sha256 = sha256 , repository_url = repository_url )
233+ platforms_for_registration .append ("{}-{}" .format (platform .os , platform .arch ))
234+
235+ buf_register_toolchains (name = name , platforms = platforms_for_registration )
236+ _register_toolchains (name )
0 commit comments