-
Notifications
You must be signed in to change notification settings - Fork 402
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
Add rust_analyzer rule to generate a rust-project.json #505
Conversation
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.
A few comments from a non maintainer 😀
You should also wire all this up to stardoc and run docs/update_docs.sh
.
This is looking super awesome!!
rust/private/rust_analyzer.bzl
Outdated
for flag in ctx.rule.attr.rustc_flags: | ||
# --cfg flags should be passed as well but as an atomic | ||
# config, not key/value | ||
if flag.startswith("--cfg"): |
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.
Should this not be --cfg=
?
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 =
is optional, and could be a space. Updated to be explicit about both possibilities.
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.
Ah cool 👍
The [6:]
was throwing me off and seemed like an oversight. Thanks for updating that 🙏
rust/private/rust_analyzer.bzl
Outdated
idx += 1 | ||
output["crates"].append(crate) | ||
|
||
ctx.actions.write(output = ctx.outputs.filename, content = struct(**output).to_json()) |
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.
You might want to add a todo or something to replace the to_json
with https://docs.bazel.build/versions/master/skylark/lib/json.html just to let future authors know about 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.
Added a TODO, it's not in any released version yet
rust/private/rust_analyzer.bzl
Outdated
aspects = [rust_analyzer_aspect], | ||
doc = "List of all targets to be included in the index", | ||
), | ||
"exec_root": attr.string( |
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.
Very interested in avoiding this. Is there no way to get this infer this information?
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 rule requires the user to manually enter their bazel info execution_root in order to locate remote crates and out_dirs. Is there a better way to retrieve this from inside starlark without resorting to genrules? I'd like to leave a genrule rewrite to a later date to unblock the relatively large win this PR brings.
Can you explain more on why needing execution_root
is necessary?
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 agree, this is the biggest issue with this PR. I believe the one real viable alternative is setting a custom --workspace_status_command
https://docs.bazel.build/versions/master/user-manual.html#flag--workspace_status_command to provide this information via an environment variable, but very interested to know if I missed another way.
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.
Maybe @damienmg or @mfarrugi might know?
The thing I want from this PR is to be able to push a change to my repo and have enabled rust-analyzer
support for anyone with no additional work. Having someone need to explicitly set the output of bazel info execution_root
sounds like it wouldn't support that. I think --workspace_status_command
might be something that works? Since I could commit a .bazelrc
file to the repo to enable these rules. But definitely interested in finding something more contained. I'm trying to find such a solution but am having no luck 😞
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 reason why it's necessary to get this information is that we must provide a path to various external source files, e.g. the rust sysroot, any third party crates you depend on, etc. All of the paths generated during the action analysis phase are relative to the execution root, and are not available via the bazel-* symlinks, so it's not possible to generate a relative path from the user's source directory to the external sources.
I'm toying with the idea of a simple genrule that can get execution_root and uses sed as a template expander, but it's not portable (e.g. to windows). There is a built-in action ctx.actions.expand_template
, but unfortunately in our case the substitution would be in an output and that rule requires it to be available as a starlark variable, so I don't think it will work.
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 should also mention that I'm really not sure how --workspace_status_command
or even the genfiles solution would work, because you can't recursively run bazel info
in order to find the workspace at runtime. So, passing the exec_root
is still the best solution I have that works at the moment, unsatisfying as it is.
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.
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.
Ok a few updates here:
-
The
bazel-{workspace}
symlink does point at the execution root, I don't know how I missed that before. I'm not sure this actually helps because I'm not sure I can get the workspace name in a normal (non-repository) rule either, and also because of (2) -
Due to how symlinks work,
bazel-bin/..
is not your current directory, it is actually a path in the execution root. For example, ifbazel-bin -> /home/vagrant/.cache/bazel/_bazel_vagrant/71ed060a30795ab0736b520a305b19cd/execroot/__main__/bazel-out/k8-fastbuild/bin
thenbazel-bin/..
is actually.../execroot/__main__/bazel-out/k8-fastbuild
This has a couple of consequences. First, the way this PR resolves local source code is wrong, but for whatever reason it doesn't look like this is breaking anything. Second, we could drop the exec_root parameter if we were willing to make the assumption that the execroot is at bazel-bin/../../../, which I think is valid and fairly safe. This is assuming that the generated rust-project.json will be used directly from bazel-bin, which is the current assumption made in this PR.
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.
For some reason I don't fully understand yet, switching to entirely relative paths based on this assumption breaks rust-analyzer.
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 is fixed by adding the gazelle-like utility run target.
rust/private/rust_analyzer.bzl
Outdated
] | ||
|
||
RustAnalyzerInfo = provider( | ||
"RustAnalyzerInfo holds rust crate metadata for targets", |
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.
Not, can you use the doc
keyword here?
@djmarcin Hey, can you take a moment to fix the conflicts? @illicitonion @hlopko Can you guys take a look at this? I think it'd be best to get this merged and allow more people to use it and make incremental improvements to it. |
ddbc8ef
to
a3a1ddb
Compare
I merged up to latest HEAD, Nevermind, it seems that my local bazel server was in a bad state. Restarting it seems to have fixed it. |
bbf3c2f
to
0a25a17
Compare
0a25a17
to
4a55fb8
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.
Looks great - thanks!
Thanks for merging, here are some quick notes on the latest "how to use" and future work. How to use:
Future work:
Known issues:
|
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'm sorry, I didn't have time to do the thorough review :/
Rust analyzer is updated very often, do you plan to keep updating our checkout with every release? If not, maybe we should add a mechanism to choose an in-workspace version instead of the one bundled with the rules..
Could you check in the docs you mentioned in the last comment? That's already better than hunting for the PR to know how to use rust-analyzer.
I'll try to look into it more thoroughly soon. Thank you so much for working on this!
to Cargo.toml files. | ||
""" | ||
|
||
load("//rust/platform:triple_mappings.bzl", "system_to_dylib_ext", "triple_to_system") |
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.
It looks like this file doesn't need anything special from the //rust/private and could potentially be moved out and only rely on the stable (non-private) APIs (BuildInfo and find_toolchain are certainly things that should be accessible through rust_common). By moving it out imho we:
- dogfood our rust_common APIs
- simplify the private package
- impose stricter layering
Would you agree that moving it out is a reasonable thing to do?
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.
Yes, I don't see any reason that would be a problem.
build_info = build_info, | ||
)] | ||
|
||
def find_proc_macro_dylib_path(toolchain, target): |
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.
Nit: Why not leading underscore?
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 update these to leading underscore in a follow-up.
This PR does not bundle rust-analyzer, it merely generates a rust-project.json file, which appears to be a stable format. |
This commit adds the instructions for setting up rust-analyzer support to the main documentation landing page. The instructions were originally given in bazelbuild#505.
This PR builds on the work in #384 to add a rust_analyzer rule which generates a rust-project.json. This file allows rust-analyzer to function without cargo by describing the code structure, layout, and dependency graph.
I think this PR is ready for review, but looking to get feedback on the following:
bazel info execution_root
in order to locate remote crates and out_dirs. Is there a better way to retrieve this from inside starlark without resorting to genrules? I'd like to leave a genrule rewrite to a later date to unblock the relatively large win this PR brings.bazel-bin
and generates relative paths for the source code under the workspace root. If there is a way to get the absolute path to the workspace root, this would not be necessary.Other than that, I think this is good to go.