-
Notifications
You must be signed in to change notification settings - Fork 480
Handle files from external repos (fix breaking change in Bazel 3.7.0) #2138
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
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
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.
Thanks for working on this! Just one question 😄
rust/private/rust.bzl
Outdated
|
||
if crate_root and (crate_root.is_source or crate_root.root.path != ctx.bin_dir.path): | ||
generated_root = ctx.actions.declare_file(paths.relativize(crate_root.short_path, package_root)) | ||
crate_root_path = paths.relativize(crate_root.path, crate_root.root.path) |
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.
Would it be simpler to just check if the path starts with ../
instead?
crate_root_path = paths.relativize(crate_root.path, crate_root.root.path) | |
if crate_root.short_path.startswith("../"): | |
generated_root = ctx.actions.declare_file(paths.relativize("external/" + crate_root.short_path[len("../"):], package_root)) | |
else: | |
generated_root = ctx.actions.declare_file(paths.relativize(crate_root.short_path, package_root)) |
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.
Honestly, I find my approach easier to read without the if/else
and no hardcoded strings (very unlikely, but they might change in the future). Maybe I can rename the variable crate_root_path
to crate_root_rel_path
to make it a bit more explicit?
In any case, no strong opinion here. If you feel like your approach is easier to read and maintain, I'm fine. You have more Bazel experience than me.
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 think explicitly handling ../
vs external/
is easier for me to maintain but would not broadly say it's more maintainable. As it's written now I feels like there's a lot going on. With either change though I think there should be a comment explaining what's happening but I do kinda like the simplicity of targeting the specific failure. If you want to keep your approach could you break it out into another function with an explanation of what's going on?
rust/private/rust.bzl
Outdated
|
||
if crate_root and (crate_root.is_source or crate_root.root.path != ctx.bin_dir.path): | ||
generated_root = ctx.actions.declare_file(paths.relativize(crate_root.short_path, package_root)) | ||
crate_root_path = paths.relativize(crate_root.path, crate_root.root.path) |
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 think explicitly handling ../
vs external/
is easier for me to maintain but would not broadly say it's more maintainable. As it's written now I feels like there's a lot going on. With either change though I think there should be a comment explaining what's happening but I do kinda like the simplicity of targeting the specific failure. If you want to keep your approach could you break it out into another function with an explanation of what's going on?
I moved the logic to another function and added some description to it with a (hopefully) good enough comment. Thanks a lot for the reviews! |
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 can take another look later today but I’m wondering why this regression wasn’t caught. Is this fixing behavior for Bazel 3? Is there some kind of regression test that can be added as part of this PR?
I think this has never been tested. The breaking change was reported in 2020 (bazelbuild/bazel#12344), and it looks like there are not so many people using In order to test this we would need to use an external repository. I don't have enough Bazel knowledge to know if this can be reproduced without actually using another repository (maybe using another |
Yeah, I introduced the code initially, and coming from a monorepo, external dependencies didn't come to mind. There is no way to test it without external dependencies, however we have examples of using external dependencies under |
Thanks for the pointers, @scentini . I've added one basic test to validate the new implementation (I've checked it fails with previous logic). |
if src_file.is_source or src_file.root.path != ctx.bin_dir.path: | ||
src_short_path = paths.relativize(src_file.path, src_file.root.path) | ||
src_symlink = ctx.actions.declare_file(paths.relativize(src_short_path, package_root)) | ||
ctx.actions.symlink( |
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.
Small nit, can you put the action to symlink back in _transform_sources
? The thing I wanted to make crystal clear is what is happening with the path manipulation here.
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.
Honestly I'm not sure about it, there will be more duplicated logic and more lines. As a newcomer, I find it harder to read (I was not used to the previous implementation).
Maybe I'm missing something and you have a much better proposal. I will work on the comment about the tests and come back here later to think about something better/easier.
def _symlink_for_non_generated_source(ctx, src_file, package_root):
if src_file.is_source or src_file.root.path != ctx.bin_dir.path:
src_short_path = paths.relativize(src_file.path, src_file.root.path)
src_symlink = ctx.actions.declare_file(paths.relativize(src_short_path, package_root))
return src_symlink
else:
return None
def _transform_sources(ctx, srcs, crate_root):
has_generated_sources = len([src for src in srcs if not src.is_source]) > 0
if not has_generated_sources:
return srcs, crate_root
package_root = paths.dirname(paths.join(ctx.label.workspace_root, ctx.build_file_path))
generated_sources = []
for src_file in srcs:
if src_file == crate_root:
continue
src_symlink = _symlink_for_non_generated_source(ctx, src_file, package_root)
if src_symlink:
ctx.actions.symlink(
output = src_symlink,
target_file = src_file,
progress_message = "Creating symlink to source file: {}".format(src_file.path),
)
generated_sources.append(src_symlink)
else:
generated_sources.append(src_file)
generated_root = crate_root
if crate_root:
src_symlink = _symlink_for_non_generated_source(ctx, crate_root, package_root)
if src_symlink:
ctx.actions.symlink(
output = src_symlink,
target_file = crate_root,
progress_message = "Creating symlink to source file: {}".format(src_file.path),
)
generated_sources.append(src_symlink)
else:
generated_sources.append(crate_root)
return generated_sources, generated_root
.bazelci/presubmit.yml
Outdated
@@ -575,6 +575,14 @@ tasks: | |||
test_flags: | |||
- "--@rules_rust//rust/toolchain/channel=nightly" | |||
- "--@rules_rust//:no_std=alloc" | |||
generated_inputs_external_repo_ubuntu2004: |
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.
Instead of adding a new job, could you not instead make a repository rule that writes a small target to an external repo and add it to https://github.com/bazelbuild/rules_rust/blob/0.27.0/test/deps.bzl ?
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 think I did the right thing here 8d0b467.
FYI. If the rust library is created in the root of the repository, then current implementation doesn't fail.
d0b6281
to
923ac33
Compare
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.
Awesome work, thank you so much!
It's been a pleasure. Looking forward to the next release. Thanks for the hard work on this project 🙌 |
…bazelbuild#2138) Fixes bazelbuild#1780 In Bazel 3.7.0, the path returned by `build_file_path` changed (bazelbuild/bazel#12344), it no longer contains the `external/<repo>` prefix for external files. This breaks the expectations of this rule in the [`paths.relativize` function](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/paths_doc.md#pathsrelativize) call. In this PR I prepend the `workspace_root` (`external/<repo>`) to `build_file_path` (`<path/in/the/repo>`), and use `path` (`external/<repo>/path/in/the/repo`) instead of `short_path` (`../<repo>/path/in/the/repo`). For files that are generated in different configurations I need to strip the `root` which contains the `bazel-out/darwin-fastbuild-ST-a1a0f4088294/bin/` that will never appear in the `package_root` path. ~Note.- I will probably need some help to add tests for this change~ I've tried to add one test --------- Co-authored-by: UebelAndre <[email protected]>
Fixes #1780
In Bazel 3.7.0, the path returned by
build_file_path
changed (bazelbuild/bazel#12344), it no longer contains theexternal/<repo>
prefix for external files. This breaks the expectations of this rule in thepaths.relativize
function call.In this PR I prepend the
workspace_root
(external/<repo>
) tobuild_file_path
(<path/in/the/repo>
), and usepath
(external/<repo>/path/in/the/repo
) instead ofshort_path
(../<repo>/path/in/the/repo
).For files that are generated in different configurations I need to strip the
root
which contains thebazel-out/darwin-fastbuild-ST-a1a0f4088294/bin/
that will never appear in thepackage_root
path.Note.- I will probably need some help to add tests for this changeI've tried to add one test