@@ -19,9 +19,10 @@ load("@rules_python//python/pip_install:pip_repository.bzl", "locked_requirement
19
19
load ("@rules_python//python/pip_install:repositories.bzl" , "pip_install_dependencies" )
20
20
load ("@rules_python//python/pip_install:requirements_parser.bzl" , parse_requirements = "parse" )
21
21
load ("@rules_python//python/private:coverage_deps.bzl" , "install_coverage_deps" )
22
- load ("@rules_python//python/private:toolchains_repo .bzl" , "get_host_os_arch" , "get_host_platform " )
22
+ load ("@rules_python//python/private:interpreter_hub .bzl" , "hub_repo " )
23
23
24
24
def _python_impl (module_ctx ):
25
+ toolchains = []
25
26
for mod in module_ctx .modules :
26
27
for toolchain_attr in mod .tags .toolchain :
27
28
python_register_toolchains (
@@ -33,11 +34,16 @@ def _python_impl(module_ctx):
33
34
register_coverage_tool = toolchain_attr .configure_coverage_tool ,
34
35
ignore_root_user_error = toolchain_attr .ignore_root_user_error ,
35
36
)
36
- host_hub_name = toolchain_attr .name + "_host_interpreter"
37
- _host_hub (
38
- name = host_hub_name ,
39
- user_repo_prefix = toolchain_attr .name ,
40
- )
37
+
38
+ # We collect all of the toolchain names to create
39
+ # the INTERPRETER_LABELS map. This is used
40
+ # by interpreter_extensions.bzl
41
+ toolchains .append (toolchain_attr .name )
42
+
43
+ hub_repo (
44
+ name = "pythons_hub" ,
45
+ toolchains = toolchains ,
46
+ )
41
47
42
48
python = module_extension (
43
49
implementation = _python_impl ,
@@ -133,89 +139,3 @@ pip = module_extension(
133
139
"parse" : tag_class (attrs = _pip_parse_ext_attrs ()),
134
140
},
135
141
)
136
-
137
- # This function allows us to build the label name of a label
138
- # that is not passed into the current context.
139
- # The module_label is the key element that is passed in.
140
- # This value provides the root location of the labels
141
- # See https://bazel.build/external/extension#repository_names_and_visibility
142
- def _repo_mapped_label (module_label , extension_name , apparent ):
143
- """Construct a canonical repo label accounting for repo mapping.
144
-
145
- Args:
146
- module_label: Label object of the module hosting the extension; see
147
- "_module" implicit attribute.
148
- extension_name: str, name of the extension that created the repo in `apparent`.
149
- apparent: str, a repo-qualified target string, but without the "@". e.g.
150
- "python38_x86_linux//:python". The repo name should use the apparent
151
- name used by the extension named by `ext_name` (i.e. the value of the
152
- `name` arg the extension passes to repository rules)
153
- """
154
- return Label ("@@{module}~{extension_name}~{apparent}" .format (
155
- module = module_label .workspace_name ,
156
- extension_name = extension_name ,
157
- apparent = apparent ,
158
- ))
159
-
160
- # We are doing some bazel stuff here that could use an explanation.
161
- # The basis of this function is that we need to create a symlink to
162
- # the python binary that exists in a different repo that we know is
163
- # setup by rules_python.
164
- #
165
- # We are building a Label like
166
- # @@rules_python~override~python~python3_x86_64-unknown-linux-gnu//:python
167
- # and then the function creates a symlink named python to that Label.
168
- # The tricky part is the "~override~" part can't be known in advance
169
- # and will change depending on how and what version of rules_python
170
- # is used. To figure that part out, an implicit attribute is used to
171
- # resolve the module's current name (see "_module" attribute)
172
- #
173
- # We are building the Label name dynamically, and can do this even
174
- # though the Label is not passed into this function. If we choose
175
- # not do this a user would have to write another 16 lines
176
- # of configuration code, but we are able to save them that work
177
- # because we know how rules_python works internally. We are using
178
- # functions from private:toolchains_repo.bzl which is where the repo
179
- # is being built. The repo name differs between host OS and platforms
180
- # and the functions from toolchains_repo gives us this functions that
181
- # information.
182
- def _host_hub_impl (repo_ctx ):
183
- # Intentionally empty; this is only intended to be used by repository
184
- # rules, which don't process build file contents.
185
- repo_ctx .file ("BUILD.bazel" , "" )
186
-
187
- # The two get_ functions we use are also utilized when building
188
- # the repositories for the different interpreters.
189
- (os , arch ) = get_host_os_arch (repo_ctx )
190
- host_platform = "{}_{}//:python" .format (
191
- repo_ctx .attr .user_repo_prefix ,
192
- get_host_platform (os , arch ),
193
- )
194
-
195
- # the attribute is set to attr.label(default = "//:_"), which
196
- # provides us the resolved, canonical, prefix for the module's repos.
197
- # The extension_name "python" is determined by the
198
- # name bound to the module_extension() call.
199
- # We then have the OS and platform specific name of the python
200
- # interpreter.
201
- label = _repo_mapped_label (repo_ctx .attr ._module , "python" , host_platform )
202
-
203
- # create the symlink in order to set the interpreter for pip.
204
- repo_ctx .symlink (label , "python" )
205
-
206
- # We use this rule to set the pip interpreter target when using different operating
207
- # systems with the same project
208
- _host_hub = repository_rule (
209
- implementation = _host_hub_impl ,
210
- local = True ,
211
- attrs = {
212
- "user_repo_prefix" : attr .string (
213
- mandatory = True ,
214
- doc = """\
215
- The prefix to create the repository name. Usually the name you used when you created the
216
- Python toolchain.
217
- """ ,
218
- ),
219
- "_module" : attr .label (default = "//:_" ),
220
- },
221
- )
0 commit comments