bazel icon indicating copy to clipboard operation
bazel copied to clipboard

`@//foo:bar` stringifies to `//foo:bar`

Open codeman9 opened this issue 3 years ago • 4 comments

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

test1.zip

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.

codeman9 avatar Jul 18 '22 22:07 codeman9

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.

Wyverald avatar Jul 19 '22 09:07 Wyverald

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?

codeman9 avatar Jul 19 '22 16:07 codeman9

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.

Wyverald avatar Jul 20 '22 11:07 Wyverald

@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.

fmeum avatar Aug 05 '22 13:08 fmeum