Skip to content

Commit d35448f

Browse files
authored
Replace apparent_repo_name with repo rule wrappers (#1650)
This presents the same API, remains compatible with both `WORKSPACE` and Bzlmod, and avoids relying on the canonical repository name format at all. Part of #1482, and supersedes the addition of `apparent_repo_name` from #1621. Also adds the `_SCALA_IMPORT_RULE_LOAD` constant in `scala/scala_maven_import_external.bzl`, which also removes `@io_bazel_rules_scala` from the `load`ed file path. It now generates the correct path with a `Label` instead. --- The goal is to maintain the ability to generate default target names from a repository name under Bzlmod. While not documented on https://bazel.build, it is documented in the Bazel source itself, even under the current 9.0.0-pre.20241105.2 prerelease: - https://github.com/bazelbuild/bazel/blob/9.0.0-pre.20241105.2/src/main/java/com/google/devtools/build/lib/cmdline/LabelParser.java#L99 Under `WORKSPACE`, the `repository_ctx.name` value served this purpose directly, as it would reflect the `name` value as provided by the caller. Under Bzlmod, this value now contains the canonical repo name, which is different than that provided by the `name` parameter. The `apparent_repo_name` utility was my first attempt to resolve this, by parsing the original `name` parameter from the canonicalized `repository_ctx.name`. I also created bazelbuild/bazel-skylib#548 to contribute `apparent_repo_name` to `bazel_skylib`, along with other proposed utilities. I quickly found better solutions to obviate the other utilities, but hung onto `apparent_repo_name`. After that pull request stagnated, I eventually realized a macro wrapper could generate a default target name for a repository_rule by duplicating the `name` attr. This isn't as easy as adding `apparent_repo_name(repository_ctx.name)` to a repo rule's implementation, but it's also not that much more work. See also this thread from the #bzlmod channel in the Bazel Slack workspace about generating default repo names: - https://bazelbuild.slack.com/archives/C014RARENH0/p1730909824656159 --- One small downside of this technique is that the macro can't be imported into a `MODULE.bazel` file directly via `use_repo_rule`. If you did want to use it in `MODULE.bazel`, you'd have to write a module extension to call it, or use `modules.as_extension` from `bazel_skylib`. I suppose that's a small price to pay for squashing a canonical repo name format dependency forever. The other small downside may be that the documentation from the original `repository_rule` doesn't automatically convey to the repo wrapper. In this case, `_alias_repository` is already internal, and the original `jvm_import_external` didn't have docstrings to begin with.
1 parent 43146ea commit d35448f

File tree

3 files changed

+27
-32
lines changed

3 files changed

+27
-32
lines changed

scala/private/macros/bzlmod.bzl

-21
This file was deleted.

scala/scala_maven_import_external.bzl

+19-8
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,12 @@ the following macros are defined below that utilize jvm_import_external:
3535
- java_import_external - to demonstrate that the original functionality of `java_import_external` stayed intact.
3636
"""
3737

38-
load("//scala/private:macros/bzlmod.bzl", "apparent_repo_name")
3938
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "read_netrc", "read_user_netrc", "use_netrc")
4039

40+
_SCALA_IMPORT_RULE_LOAD = (
41+
"load(\"%s\", \"scala_import\")" % Label("//scala:scala_import.bzl")
42+
)
43+
4144
# https://github.com/bazelbuild/bazel/issues/13709#issuecomment-1336699672
4245
def _get_auth(ctx, urls):
4346
"""Given the list of URLs obtain the correct auth dict."""
@@ -60,12 +63,12 @@ _PASS_PROPS = (
6063

6164
_FETCH_SOURCES_ENV_VAR_NAME = "BAZEL_JVM_FETCH_SOURCES"
6265

63-
def _jvm_import_external(repository_ctx):
66+
def _jvm_import_external_impl(repository_ctx):
6467
"""Implementation of `java_import_external` rule."""
6568
if (repository_ctx.attr.generated_linkable_rule_name and
6669
not repository_ctx.attr.neverlink):
6770
fail("Only use generated_linkable_rule_name if neverlink is set")
68-
repo_name = apparent_repo_name(repository_ctx)
71+
repo_name = repository_ctx.name
6972
name = repository_ctx.attr.generated_rule_name or repo_name
7073
urls = repository_ctx.attr.jar_urls
7174
if repository_ctx.attr.jar_sha256:
@@ -138,7 +141,7 @@ def _jvm_import_external(repository_ctx):
138141
"",
139142
"alias(",
140143
" name = \"jar\",",
141-
" actual = \"//:%s\"," % repo_name,
144+
" actual = \"//:%s\"," % name,
142145
")",
143146
"",
144147
]))
@@ -224,8 +227,8 @@ def _serialize_given_rule_import(
224227
lines.append("")
225228
return lines
226229

227-
jvm_import_external = repository_rule(
228-
implementation = _jvm_import_external,
230+
_jvm_import_external = repository_rule(
231+
implementation = _jvm_import_external_impl,
229232
attrs = {
230233
"rule_name": attr.string(mandatory = True),
231234
"licenses": attr.string_list(mandatory = True, allow_empty = False),
@@ -254,10 +257,18 @@ jvm_import_external = repository_rule(
254257
environ = [_FETCH_SOURCES_ENV_VAR_NAME],
255258
)
256259

260+
def jvm_import_external(**kwargs):
261+
"""Wraps `_jvm_import_external` to pass `name` as `generated_target_name`.
262+
263+
If `generated_rule_name` is specified already, this is a noop.
264+
"""
265+
generated_rule_name = kwargs.pop("generated_rule_name", kwargs.get("name"))
266+
_jvm_import_external(generated_rule_name = generated_rule_name, **kwargs)
267+
257268
def scala_maven_import_external(
258269
artifact,
259270
server_urls,
260-
rule_load = "load(\"@io_bazel_rules_scala//scala:scala_import.bzl\", \"scala_import\")",
271+
rule_load = _SCALA_IMPORT_RULE_LOAD,
261272
fetch_sources = False,
262273
**kwargs):
263274
jvm_maven_import_external(
@@ -299,7 +310,7 @@ def jvm_maven_import_external(
299310
jvm_import_external(jar_urls = jar_urls, srcjar_urls = srcjar_urls, coordinates = artifact, **kwargs)
300311

301312
def scala_import_external(
302-
rule_load = "load(\"@io_bazel_rules_scala//scala:scala_import.bzl\", \"scala_import\")",
313+
rule_load = _SCALA_IMPORT_RULE_LOAD,
303314
**kwargs):
304315
jvm_import_external(
305316
rule_name = "scala_import",

third_party/repositories/repositories.bzl

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
load("//scala/private:macros/bzlmod.bzl", "apparent_repo_name")
21
load(
32
"//third_party/repositories:scala_2_11.bzl",
43
_artifacts_2_11 = "artifacts",
@@ -129,13 +128,13 @@ def repositories(
129128
# See: https://github.com/bazelbuild/rules_scala/pull/1573
130129
# Hopefully we can deprecate and remove it one day.
131130
if suffix and scala_version == SCALA_VERSION:
132-
_alias_repository(name = id, target = artifact_repo_name)
131+
_alias_repository_wrapper(name = id, target = artifact_repo_name)
133132

134133
def _alias_repository_impl(rctx):
135134
""" Builds a repository containing just two aliases to the Scala Maven artifacts in the `target` repository. """
136135

137136
format_kwargs = {
138-
"name": apparent_repo_name(rctx),
137+
"name": rctx.attr.default_target_name,
139138
"target": rctx.attr.target,
140139
}
141140
rctx.file("BUILD", """alias(
@@ -154,6 +153,12 @@ def _alias_repository_impl(rctx):
154153
_alias_repository = repository_rule(
155154
implementation = _alias_repository_impl,
156155
attrs = {
156+
"default_target_name": attr.string(mandatory = True),
157157
"target": attr.string(mandatory = True),
158158
},
159159
)
160+
161+
def _alias_repository_wrapper(**kwargs):
162+
"""Wraps `_alias_repository` to pass `name` as `default_target_name`."""
163+
default_target_name = kwargs.pop("default_target_name", kwargs.get("name"))
164+
_alias_repository(default_target_name = default_target_name, **kwargs)

0 commit comments

Comments
 (0)