`@//foo:bar` stringifies to `//foo:bar`
Description of the bug:
There is a rule in rules_apple called provisioning_profiles_repository. This rule has an attribute fallback_profiles of type Label. Passing a string the references the main repository results in that part of the label being discarded in the output BUILD file. For example, a string like:
...
fallback_profiles = @main-repo//provisioning/profiles:my_profiles
...
or
...
fallback_profiles = @//provisioning/profiles:my_profiles
...
results in a BUILD file like:
...
alias(
name = "fallback_profiles",
actual = "//provisioning/profiles:debug_profiles",
visibility = ["//visibility:public"],
)
...
which no longer has the @main-repo portion and results in a failure like:
/private/var/tmp/_bazel_codyv/34ff94ddc17314b0784f10abb6acba67/external/local_provisioning_profiles/BUILD.bazel:13:6: no such package '@local_provisioning_profiles//provisioning/profiles': BUILD file not found in directory 'provisioning/profiles' of external repository @local_provisioning_profiles
I've tracked it down to this commit: b21069fd6f2440f90c57014b90063760223777e0 as being the cause.
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Change .bazelversion:
# .bazelversion
# b21069fd6f2440f90c57014b90063760223777e0 <- Fails
# cc55400e614e4e301244cc7c338ee3ea89424ce0 <- Works
run: bazel build //:test
In the "working" scenario, an error will be produced:
ERROR: /Users/codyv/Developer/bazelbuild/test1/BUILD:3:27: in local_provisioning_profile rule //:test:
/Users/codyv/Developer/bazelbuild/test1/test1.bzl:33:5: The following files have no generating action:
test.mobileprovision
and the [path/to/]external/my_profiles/BUILD.bazel will look like:
filegroup(
name = "profiles",
srcs = glob(["profiles/*.mobileprovision"], allow_empty = True),
visibility = ["//visibility:public"],
)
filegroup(
name = "empty",
srcs = [],
visibility = ["//visibility:public"],
)
alias(
name = "fallback_profiles",
actual = "@my-repo//provisioning/profiles:debug_profiles",
visibility = ["//visibility:public"],
)
and with the "Failure" hash, the error looks like:
ERROR: /private/var/tmp/_bazel_codyv/559ac1f1e133c637b2b59c5cce0ab6cc/external/my_profiles/BUILD.bazel:13:6: no such package '@my_profiles//provisioning/profiles': BUILD file not found in directory 'provisioning/profiles' of external repository @my_profiles. Add a BUILD file to a directory to mark it as a package. and referenced by '@my_profiles//:fallback_profiles'
and the [path/to/]external/my_profiles/BUILD.bazel will look like:
filegroup(
name = "profiles",
srcs = glob(["profiles/*.mobileprovision"], allow_empty = True),
visibility = ["//visibility:public"],
)
filegroup(
name = "empty",
srcs = [],
visibility = ["//visibility:public"],
)
alias(
name = "fallback_profiles",
actual = "//provisioning/profiles:debug_profiles",
visibility = ["//visibility:public"],
)
Notice the difference in the actual value.
Which operating system are you running Bazel on?
macOS 12.4
What is the output of bazel info release?
2022/07/18 15:50:18 Using unreleased version at commit b21069fd6f2440f90c57014b90063760223777e0
If bazel info release returns development version or (@non-git), tell us how you built Bazel.
Using bazelisk at the specified hash
What's the output of git remote get-url origin; git rev-parse master; git rev-parse HEAD ?
[email protected]:bazelbuild/bazel.git
03493b60baba5ca6780914715680d03791b39efc
03493b60baba5ca6780914715680d03791b39efc
Have you found anything relevant by searching the web?
https://github.com/bazelbuild/bazel/commit/b21069fd6f2440f90c57014b90063760223777e0 is the commit that introduces this change of behavior.
Any other information, logs, or outputs that you want to share?
After manually adding in @my-repo or @ for the actual parameter in the BUILD.bazel file, then the expected behavior is shown.
Thanks for the very detailed report! I'm acutely aware of this -- and unfortunately this is not trivial to fix. The underlying reason is that the label @//foo:bar, when stringified, becomes //foo:bar. This is a very old behavior that has been kept in Bazel since its early days.
The commit that introduced this bug (https://github.com/bazelbuild/bazel/commit/b21069fd6f2440f90c57014b90063760223777e0) actually fixes a related bug. In a workspace named "ws", @ws//foo:bar should be an alias of @//foo:bar; but before https://github.com/bazelbuild/bazel/commit/b21069fd6f2440f90c57014b90063760223777e0, @ws//foo:bar and @//foo:bar were often distinct labels. The fake repo @ws is actually a local_repository that simply points to the directory .. This means that @ws//foo:bar and @//foo:bar look and behave the same, but don't compare equal -- which spells trouble for stuff like toolchains and providers. https://github.com/bazelbuild/bazel/commit/b21069fd6f2440f90c57014b90063760223777e0 fixed it so that @ws//foo:bar gets correctly aliased to @//foo:bar in many more cases, which unfortunately means that we now hit this stringification bug.
Now, in order to fix this issue, we'd need to make sure that @//foo:bar doesn't lose the @ when stringified. This is a rather big behavior change and I'd need to first make sure we don't break too many people. But rest assured that fixing this is a top priority for me right now.
I appreciate the information and understand that something like this may have far reaching implications. Is there anything I can do to workaround this in the meantime?
There's unfortunately no easy band-aid solution that I can think of -- using a Bazel version pre-https://github.com/bazelbuild/bazel/commit/b21069fd6f2440f90c57014b90063760223777e0 could be fine for you, though it might reintroduce the fixed bug and cause toolchain resolution failures.
@codeman9 If you really need to work around this, you could probably define an alias in a non-main repository pointing to the file and then provide the label of the alias to the repository rule.