-
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
Perform builtins injection for WORKSPACE-loaded bzl files. #18022
Conversation
c95daf9
to
14212da
Compare
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Outdated
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java
Show resolved
Hide resolved
@@ -135,6 +135,10 @@ public SkyValue compute(SkyKey skyKey, Environment env) | |||
return computeForModuleExtensionRepo( | |||
repositoryName, moduleExtensionId.get(), extensionEvalValue, bazelDepGraphValue); | |||
} | |||
|
|||
if (RepositoryName.BAZEL_TOOLS.equals(repositoryName)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the justification for this check here?
The complexity of the code here is going slightly past my review capabilities and my first thought is this is just making the tests to pass and the code even more complex.
Similar complexity to this one is happening in BzlloadFunction.getRepositoryMapping, which I imagine is calling the location here.
Is there a way to simplify it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't understand this check. @bazel_tools
should have its repo mapping calculated just like any other Bazel module, not the VALUE_FOR_ROOT_MODULE_WITHOUT_REPOS
sentinel value.
Similar complexity to this one is happening in BzlloadFunction.getRepositoryMapping, which I imagine is calling the location here.
Indeed, BzlLoadFunction#getRepositoryMapping
calls to RepositoryMappingFunction
, but the former is more complex because repo mapping computation for .bzl files has extra considerations due to some "partial" loading. RepositoryMappingFunction
deals with the general case of "all WORKSPACE/Bzlmod/injection has finished and we're just loading a normal BUILD file (and similar environments) now".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check avoids a fundamental cycle when bzlmod is enabled: workspace loading -> @_builtins
loading -> @_builtins
repository mapping -> @bazel_tools
repository mapping -> //external
package -> workspace loading.
The effect of this check, I believe, is you can't declare a repo_mapping for @bazel_tools
in WORKSPACE. That's fine, I think? I'm certainly open to any other ideas on how to resolve this cycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditions that lead to this line are (I took the liberty to enumerate them using and IDE, because I find it hard to follow {,} on github):
- enableBzlMod
- not @_builtins
- not (main repo && rootModuleShouldSeeWorkspaceRepos)
- bazelDepGraphValue.getCanonicalRepoNameLookup().get(repositoryName) == null
- maybeGetModuleExtensionForRepo(repositoryName) == null
The conditions seem mostly fine, providing we can't use bazel_tools
for either a module name or module extension within bzlmod. Is this true?
In case it can be used, you're back forming a cycle as soon as the new bazel_tools
uses builtins
. Or even worse, you don't allow this new repo to be used from anywhere (even when it should be locally available).
What I'm also concerned is, this doesn't seem to handle the same cycle when not enableBzlMod
.
Also, because the cycle is started from @_builtins repository mapping request. I think this would be better put into BzlloadFunction.getRepositoryMapping
, so that it covers only @_builtins -> @bazel_tools edge.
In that function it might even be clearer which cases need cycle-breaking.
(I'm not an expert in SkyFrame, I've written what I think and not everything might be completely accurate)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also suggest adding a test for the minimal reproduction in the bug, having bzlmod enabled and disabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hang on, I still don't understand. the branch on line 119 should include @bazel_tools
, as bazel_tools
is a builtin module ("builtin" as in "shipped with Bazel", not as in @_builtins
). So this check on line 139 should never occur.
(In other words, from what Ivo wrote, the fourth bullet point should not hold.)
Alternatively, the question is -- how come this cycle wasn't a problem before? How does injection builtins for WORKSPACE-loaded .bzl files affect the repo mapping calculation of @bazel_tools
when Bzlmod is enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, there's more context about the extremely specific situations this cycle occurs in.
Hang on, I still don't understand. the branch on line 119 should include
@bazel_tools
, asbazel_tools
is a builtin module ("builtin" as in "shipped with Bazel", not as in@_builtins
). So this check on line 139 should never occur.
That is mostly true. In practice, bazel cmd --enable_bzlmod
avoids the cycle I describe by loading the repository mapping from src/MODULE.tools
. The cycle only happens in some Java tests that don't set up a MODULE.bazel
for @bazel_tools
.
Come to think of it, maybe I should simply improve the tests to be more realistic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me now. @Wyverald any concerns?
14212da
to
c66e7ac
Compare
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/packages/BazelStarlarkEnvironment.java
Show resolved
Hide resolved
src/main/java/com/google/devtools/build/lib/skyframe/BzlLoadFunction.java
Show resolved
Hide resolved
@@ -135,6 +135,10 @@ public SkyValue compute(SkyKey skyKey, Environment env) | |||
return computeForModuleExtensionRepo( | |||
repositoryName, moduleExtensionId.get(), extensionEvalValue, bazelDepGraphValue); | |||
} | |||
|
|||
if (RepositoryName.BAZEL_TOOLS.equals(repositoryName)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The conditions that lead to this line are (I took the liberty to enumerate them using and IDE, because I find it hard to follow {,} on github):
- enableBzlMod
- not @_builtins
- not (main repo && rootModuleShouldSeeWorkspaceRepos)
- bazelDepGraphValue.getCanonicalRepoNameLookup().get(repositoryName) == null
- maybeGetModuleExtensionForRepo(repositoryName) == null
The conditions seem mostly fine, providing we can't use bazel_tools
for either a module name or module extension within bzlmod. Is this true?
In case it can be used, you're back forming a cycle as soon as the new bazel_tools
uses builtins
. Or even worse, you don't allow this new repo to be used from anywhere (even when it should be locally available).
What I'm also concerned is, this doesn't seem to handle the same cycle when not enableBzlMod
.
Also, because the cycle is started from @_builtins repository mapping request. I think this would be better put into BzlloadFunction.getRepositoryMapping
, so that it covers only @_builtins -> @bazel_tools edge.
In that function it might even be clearer which cases need cycle-breaking.
(I'm not an expert in SkyFrame, I've written what I think and not everything might be completely accurate)
c66e7ac
to
8ad943f
Compare
Hi @comius, Since I can see that this PR has been approved, please let me know whether I should proceed with importing it. Thanks! |
bazelbuild#17713 Closes bazelbuild#18022. PiperOrigin-RevId: 525350732 Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731
bazelbuild#17713 Closes bazelbuild#18022. PiperOrigin-RevId: 525350732 Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731
#17713 Closes #18022. PiperOrigin-RevId: 525350732 Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731 Co-authored-by: Benjamin Peterson <[email protected]>
#17713