Skip to content
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

Closed

Conversation

benjaminp
Copy link
Collaborator

@github-actions github-actions bot added the awaiting-review PR is awaiting review from an assigned reviewer label Apr 10, 2023
@benjaminp benjaminp force-pushed the workspace-bzl-injection branch 7 times, most recently from c95daf9 to 14212da Compare April 11, 2023 03:12
@sgowroji sgowroji added the team-Loading-API BUILD file and macro processing: labels, package(), visibility, glob label Apr 11, 2023
@comius comius self-requested a review April 11, 2023 10:06
@comius comius self-assigned this Apr 11, 2023
@comius
Copy link
Contributor

comius commented Apr 11, 2023

cc @Wyverald @meteorcloudy @brandjon

@@ -135,6 +135,10 @@ public SkyValue compute(SkyKey skyKey, Environment env)
return computeForModuleExtensionRepo(
repositoryName, moduleExtensionId.get(), extensionEvalValue, bazelDepGraphValue);
}

if (RepositoryName.BAZEL_TOOLS.equals(repositoryName)) {
Copy link
Contributor

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?

Copy link
Member

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

Copy link
Collaborator Author

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.

Copy link
Contributor

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)

Copy link
Contributor

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.

Copy link
Member

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?

Copy link
Collaborator Author

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

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.

Copy link
Contributor

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?

@@ -135,6 +135,10 @@ public SkyValue compute(SkyKey skyKey, Environment env)
return computeForModuleExtensionRepo(
repositoryName, moduleExtensionId.get(), extensionEvalValue, bazelDepGraphValue);
}

if (RepositoryName.BAZEL_TOOLS.equals(repositoryName)) {
Copy link
Contributor

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)

@sgowroji
Copy link
Member

Hi @comius, Since I can see that this PR has been approved, please let me know whether I should proceed with importing it. Thanks!

@comius
Copy link
Contributor

comius commented Apr 17, 2023

Hi @comius, Since I can see that this PR has been approved, please let me know whether I should proceed with importing it. Thanks!

Please wait for @Wyverald's approval as well. Thanks.

@Wyverald Wyverald added awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally and removed awaiting-review PR is awaiting review from an assigned reviewer labels Apr 17, 2023
@Pavank1992 Pavank1992 removed the awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally label Apr 19, 2023
@benjaminp benjaminp deleted the workspace-bzl-injection branch April 19, 2023 13:19
fweikert pushed a commit to fweikert/bazel that referenced this pull request May 25, 2023
bazelbuild#17713

Closes bazelbuild#18022.

PiperOrigin-RevId: 525350732
Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731
iancha1992 pushed a commit to iancha1992/bazel that referenced this pull request Jun 29, 2023
bazelbuild#17713

Closes bazelbuild#18022.

PiperOrigin-RevId: 525350732
Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731
iancha1992 added a commit that referenced this pull request Jun 30, 2023
#17713

Closes #18022.

PiperOrigin-RevId: 525350732
Change-Id: I869653fcd6d4a82ccca49f14e66245c182062731

Co-authored-by: Benjamin Peterson <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Loading-API BUILD file and macro processing: labels, package(), visibility, glob
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants