-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Description
Description of the bug:
When building under WORKSPACE
with Bazel 8.1.0 (and 8.1.0rc2), repository_ctx.original_name
will be the empty string. This produces default BUILD
targets with empty names inside generated repos (the use case from #24467), breaking the build.
Commit 8bcfb06 introduced repository_ctx.original_name
for release in 8.1.0 (first appearing in 8.1.0rc2), closing #24467 and #25121. In bazel-contrib/rules_scala#1694, I introduced code like this to use it when available, which breaks when building with Bazel 8.1.0 and --enable_workspace
:
# Replace with rctx.original_name once all supported Bazels have it
"name": getattr(rctx, "original_name", rctx.attr.default_target_name),
It would be good to have this field set regardless when using WORKSPACE
, even though it would duplicate repository_ctx.name
, to avoid having to write code like this (which does work, but is quite clumsy):
"name": (
getattr(rctx, "original_name", rctx.attr.default_target_name) or
rctx.name
),
An alternative would be to remove it from WORKSPACE
builds altogether, but it would be great to have it work with WORKSPACE
so people can just use repository_ctx.original_name
directly and forget about it once Bazel 8 is the oldest supported version (i.e., so the getattr
checks can go away sooner than later).
(Sorry I didn't actually get around to testing this case when 8.1.0rc2 came out; I only used it to check #25192.)
Which category does this issue belong to?
Core
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
WORKSPACE
:
workspace(name = "original-name-repro")
load("//:repro.bzl", "repro_repo")
repro_repo(name = "name", default_target_name = "name")
MODULE.bazel
:
module(name = "original-name-repro", version = "0.0.0")
repro_repo = use_repo_rule("//:repro.bzl", "repro_repo")
repro_repo(name = "name", default_target_name = "name")
BUILD
:
genrule(
name = "name",
srcs = ["@name"],
outs = ["name.txt"],
cmd = "cat $(execpath @name) > \"$@\"",
)
repro.bzl
:
_build_template = """genrule(
name = "{target_name}",
outs = ["name.txt"],
cmd = "echo '{target_name}' > \\"$@\\"",
visibility = ["//visibility:public"],
)
"""
def _repro_repo_impl(rctx):
target_name = getattr(rctx, "original_name", rctx.attr.default_target_name)
if hasattr(rctx, "original_name"):
print("name: '%s' original_name: '%s' target_name: '%s'" % (
rctx.name, rctx.original_name, target_name)
)
else:
print("original_name not available")
rctx.file("BUILD", _build_template.format(target_name = target_name))
repro_repo = repository_rule(
implementation = _repro_repo_impl,
attrs= {
"default_target_name": attr.string(mandatory = True),
},
)
Then running the following (edited for brevity):
$ USE_BAZEL_VERSION=7.5.0 bazel build --enable_workspace --noenable_bzlmod //:name && echo "NAME: $(< bazel-bin/name.txt)"
DEBUG: .../repro.bzl:17:14: original_name not available
Target //:name up-to-date:
bazel-bin/name.txt
NAME: name
$ USE_BAZEL_VERSION=7.5.0 bazel build --noenable_workspace --enable_bzlmod //:name && echo "NAME: $(< bazel-bin/name.txt)"
DEBUG: .../repro.bzl:17:14: original_name not available
Target //:name up-to-date:
bazel-bin/name.txt
NAME: name
$ USE_BAZEL_VERSION=8.1.0 bazel build --noenable_workspace --enable_bzlmod //:name && echo "NAME: $(< bazel-bin/name.txt)"
DEBUG: .../repro.bzl:13:14: name: '+_repo_rules+name' original_name: 'name' target_name: 'name'
Target //:name up-to-date:
bazel-bin/name.txt
NAME: name
$ USE_BAZEL_VERSION=8.1.0 bazel build --enable_workspace --noenable_bzlmod //:name && echo "NAME: $(< bazel-bin/name.txt)"
DEBUG: .../repro.bzl:13:14: name: 'name' original_name: '' target_name: ''
ERROR: Traceback (most recent call last):
File ".../external/name/BUILD", line 1, column 8, in <toplevel>
genrule(
Error in genrule: illegal rule name: : invalid target name '': empty target name
ERROR: .../external/name/BUILD: no such target '@@name//:name':
target 'name' not declared in package '' defined by .../external/name/BUILD
ERROR: .../BUILD:1:8: no such target '@@name//:name':
target 'name' not declared in package '' defined by .../external/name/BUILD
and referenced by '//:name'
ERROR: Analysis of target '//:name' failed; build aborted: Analysis failed
ERROR: Build did NOT complete successfully
$ cat "$(bazel info output_base)/external/name/BUILD"
genrule(
name = "",
outs = ["name.txt"],
cmd = "echo '' > \"$@\"",
visibility = ["//visibility:public"],
)
Which operating system are you running Bazel on?
macOS 15.3.1 (24D70)
What is the output of bazel info release
?
release 8.1.0
If bazel info release
returns development version
or (@non-git)
, tell us how you built Bazel.
No response
What's the output of git remote get-url origin; git rev-parse HEAD
?
If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
After encountering a build breakage due to empty default target names in generated repositories, I added debug code like the following:
if hasattr(rctx, "original_name"):
print("name: '%s' original_name: '%s'" % (rctx.name, rctx.original_name)
It printed lines like this under Bzlmod:
DEBUG: .../rules_scala/third_party/repositories/repositories.bzl:144:14:
name: '+scala_deps+scala_proto_rules_scalapb_protoc_bridge'
original_name: 'scala_proto_rules_scalapb_protoc_bridge'
and lines like this under WORKSPACE
:
DEBUG: .../rules_scala/third_party/repositories/repositories.bzl:144:14:
name: 'scala_proto_rules_scalapb_protoc_bridge'
original_name: ''