-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bzlmod: allow repos to be visible to other module extensions #19301
Comments
FWIW, I encountered a similar situation when attempting to modularize Kythe. We depend on https://github.com/google/brotli from both C++ and Go. The Go module also depends on the C++ library, but that library can't be handled directly by Go. In order to accomplish this, I had to patch the BUILD file to use the canonical repo path to the non-modular C++ repository. Were that repository to be a modular dependency, this gets really fiddly and flaky. Similarly, any kind of shared dependency that needs to bridge external package managers becomes challenging without someway of making that dependency known and available to the language-specific module extension. |
While this doesn't help in the general case, in the Go case you can just add the Go module with patches to the BCR as a Bazel module and But I fully agree we need something more flexible and generally applicable to add the repo mapping entries for patches. |
This can work as long as the Similar for @shahms, as long as you make sure the tag attribute has type "label", you should be able to pass that label around (in a capability-passing fashion, almost). |
@shahms use case, which is similar to bazelbuild/rules_python#48 (comment), also requires a way to reference this label from (patched) BUILD files. I can think of three ways to make this work:
|
I found a fourth option that I currently like best: |
So IIUC the capability is there (using label-typed attributes), just the usability is really bad because the user needs to somehow translate a BUILD file patch containing single- Assuming that it is, I'm sympathetic to the concern and agree that we should have a better story for this use case. But first I wanted to make sure we're aware of a specific technical challenge, which is that any "repo mapping injection" we do is subject to conflicts. Suppose Now, going over @fmeum's suggestions:
The "reverse use_repo"/"make_visible_to" idea brought up in the other thread also suffers from the injection conflict problem, but has the advantage of being more ergonomic -- no funny label business. To mitigate the injection conflict problem, I wonder if we can limit the scope of an injected repo mapping to select repos generated by the extension. Essentially this would be bringing back the But wait, isn't that #17493 (comment), where you said this was infeasible?? Well, not quite -- the This approach still requires the user to "expose" a repo to an extension via a label (a capability), but then the extension can decide smartly what to do with that capability. Admittedly usability still isn't great; we could repurpose the "make_visible_to" idea to improve usability ( |
In the internal team discussion we had on how to pin a module extension generated repo, instead of using
If we only use the repo mapping functionality alone, for the go use case, it would be:
|
@bazel-io fork 7.1.0 |
OK, so it looks like the biggest "hole" in this new idea is that the overridden repo is still accessible through its original canonical name. This hole is rather hard to plug, since we'd need some sort of repo-level alias (#19927) for this to work. (The idea being that the overridden repo's canonical name aliases to the overriding repo's canonical name.) While this is easy to do on a surface level (just make a symlink), the proper fix for this is nigh impossible (involves making labels compare equal while cognizant of repo-level aliases). We could work around this issue in the "
While that's true, I'm still kind of sympathetic to the "patching MODULE.bazel with |
Does that mean we have this plan?
This looks good to me (and doable in time for 7.4.0/8.0.0) |
SGTM. One last bikeshed for the road: I'd prefer the name |
Some edge cases that we should keep in mind when implementing this: ext = use_repo("@other_module//:ext.bzl", "ext")
use_repo(ext, "foo")
# Overriding one repo in an extension with another repo from that extension.
override_repo(ext, bar = "foo") ext = use_repo("//:ext.bzl", "ext")
use_repo(ext, "foo")
ext2 = use_repo("//:ext2.bzl", "ext2")
use_repo(ext2, "bar")
# Overriding a repo in an extension defined by the main repo.
override_repo(ext, foo = "bar") ext = use_repo("@other_module//:ext.bzl", "ext")
use_repo(ext, "foo")
ext2 = use_repo("@other_module//:ext2.bzl", "ext2")
use_repo(ext2, "bar")
ext3 = use_repo("@other_module//:ext3.bzl", "ext3")
use_repo(ext3, "baz")
# Overriding a repo with an overridden repo.
override_repo(ext2, bar = "foo")
override_repo(ext3, baz = "bar") ext = use_repo("@other_module//:ext.bzl", "ext")
use_repo(ext, "foo")
ext2 = use_repo("@other_module//:ext2.bzl", "ext2")
use_repo(ext2, "bar")
ext3 = use_repo("@other_module//:ext3.bzl", "ext3")
use_repo(ext3, "baz")
# Overriding a repo with an overridden repo in a way that forms a cycle.
override_repo(ext2, bar = "foo")
override_repo(ext3, baz = "bar")
override_repo(ext, foo = "baz")
|
@fmeum can this be closed now? |
Work towards bazelbuild#19301 RELNOTES: Patches to the module file in `single_version_override` are now effective as long as the patch file lies in the root module. Closes bazelbuild#23536. PiperOrigin-RevId: 678347809 Change-Id: I6a3c4664e55cff90c8e42795f95d8ef211348ca9
Work towards bazelbuild#19301 RELNOTES: Patches to the module file in `single_version_override` are now effective as long as the patch file lies in the root module. Closes bazelbuild#23536. PiperOrigin-RevId: 678347809 Change-Id: I6a3c4664e55cff90c8e42795f95d8ef211348ca9
Work towards bazelbuild#19301 RELNOTES: Patches to the module file in `single_version_override` are now effective as long as the patch file lies in the root module. Closes bazelbuild#23536. PiperOrigin-RevId: 678347809 Change-Id: I6a3c4664e55cff90c8e42795f95d8ef211348ca9
There are some aspects of
local_repository(
name = "zlib",
...
)
foo_deps = use_extension(..., "foo_deps")
inject_repo(foo_deps, com_github_zlib = "zlib")
# Disallow this:
use_repo(foo_deps, "com_github_zlib") In this example, instead of having
local_repository(
name = "googleapis",
...
)
bar_deps = use_extension(..., "bar_deps")
override_repo(bar_deps, "googleapis")
use_repo(bar_deps, bar_googleapis = "googleapis")
foo_deps = use_extension(..., "foo_deps")
override_repo(foo_deps, com_github_google_googleapis = "googleapis")
use_repo(foo_deps, "com_github_googleapis") Assuming that Since bazel_dep(
name = "googleapis",
dev_dependency = True,
...
)
bar_deps = use_extension(..., "bar_deps")
override_repo(bar_deps, "googleapis")
foo_deps = use_extension(..., "foo_deps")
override_repo(foo_deps, com_github_google_googleapis = "googleapis") This looks much nicer, but it's flawed in a subtle way: When the module is not the root module, the overrides won't be applied and all references to I first thought that we could prohibit I don't see a better solution than having Curious to hear your thoughts about this! |
Work towards bazelbuild#19301 Fixes bazelbuild#23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes bazelbuild#23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1)
Work towards bazelbuild#19301 Fixes bazelbuild#23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes bazelbuild#23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1)
Work towards bazelbuild#19301 Fixes bazelbuild#23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes bazelbuild#23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1)
Work towards bazelbuild#19301 Fixes bazelbuild#23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes bazelbuild#23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1)
Work towards bazelbuild#19301 Fixes bazelbuild#23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes bazelbuild#23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1)
Work towards #19301 Fixes #23580 RELNOTES: `override_repo` and `inject_repo` can be used to override and inject repos in module extensions. Closes #23534. PiperOrigin-RevId: 678139661 Change-Id: Iea7caca949c00e701f056c1037e273fee9740e93 (cherry picked from commit 46341b1) Fixes #23724 Fixes #23799 Also includes: * Disallow importing injected repos (8472c9d) --------- Co-authored-by: Xùdōng Yáng <[email protected]>
Description of the feature request:
In certain situations, there exists a need to have a module extension be able to have visibility of repositories that are created by other module extensions.
Let's take
go_sdk
module extension for example inrules_go
.I have some repo declared locally in the main module, say for example
@go_sdk_linux_amd64
is the name of the repo.Now, I want to have the
go_sdk
module extension load this with something that is similar to theWORKSPACE
repository rulego_wrap_sdk
: (https://github.com/bazelbuild/rules_go/blob/master/go/private/sdk.bzl#L372-L391)The issue here, is that if I make a tag (for example
go_sdk.wrap(name = "@go_sdk_linux_amd64")
, the build will fail because the module extensiongo_deps
doesn't see the repo @go_sdk_linux_amd64Which category does this issue belong to?
No response
What underlying problem are you trying to solve with this feature?
The ability to use a repo that is declared in the main module in a call to a module extension that is externally declared.
Which operating system are you running Bazel on?
Linux
What is the output of
bazel info release
?release 6.3.1
If
bazel info release
returnsdevelopment 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 master; git rev-parse HEAD
?Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response
The text was updated successfully, but these errors were encountered: