xref: /aosp_15_r20/external/bazelbuild-rules_rust/tools/rust_analyzer/lib.rs (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1 use std::collections::HashMap;
2 use std::path::Path;
3 use std::process::Command;
4 
5 use anyhow::anyhow;
6 use runfiles::Runfiles;
7 
8 mod aquery;
9 mod rust_project;
10 
generate_crate_info( bazel: impl AsRef<Path>, workspace: impl AsRef<Path>, rules_rust: impl AsRef<str>, targets: &[String], ) -> anyhow::Result<()>11 pub fn generate_crate_info(
12     bazel: impl AsRef<Path>,
13     workspace: impl AsRef<Path>,
14     rules_rust: impl AsRef<str>,
15     targets: &[String],
16 ) -> anyhow::Result<()> {
17     log::debug!("Building rust_analyzer_crate_spec files for {:?}", targets);
18 
19     let output = Command::new(bazel.as_ref())
20         .current_dir(workspace.as_ref())
21         .env_remove("BAZELISK_SKIP_WRAPPER")
22         .env_remove("BUILD_WORKING_DIRECTORY")
23         .env_remove("BUILD_WORKSPACE_DIRECTORY")
24         .arg("build")
25         .arg("--norun_validations")
26         .arg(format!(
27             "--aspects={}//rust:defs.bzl%rust_analyzer_aspect",
28             rules_rust.as_ref()
29         ))
30         .arg("--output_groups=rust_analyzer_crate_spec,rust_generated_srcs")
31         .args(targets)
32         .output()?;
33 
34     if !output.status.success() {
35         return Err(anyhow!(
36             "bazel build failed:({})\n{}",
37             output.status,
38             String::from_utf8_lossy(&output.stderr)
39         ));
40     }
41 
42     Ok(())
43 }
44 
write_rust_project( bazel: impl AsRef<Path>, workspace: impl AsRef<Path>, rules_rust_name: &impl AsRef<str>, targets: &[String], execution_root: impl AsRef<Path>, output_base: impl AsRef<Path>, rust_project_path: impl AsRef<Path>, ) -> anyhow::Result<()>45 pub fn write_rust_project(
46     bazel: impl AsRef<Path>,
47     workspace: impl AsRef<Path>,
48     rules_rust_name: &impl AsRef<str>,
49     targets: &[String],
50     execution_root: impl AsRef<Path>,
51     output_base: impl AsRef<Path>,
52     rust_project_path: impl AsRef<Path>,
53 ) -> anyhow::Result<()> {
54     let crate_specs = aquery::get_crate_specs(
55         bazel.as_ref(),
56         workspace.as_ref(),
57         execution_root.as_ref(),
58         targets,
59         rules_rust_name.as_ref(),
60     )?;
61 
62     let path = runfiles::rlocation!(
63         Runfiles::create()?,
64         "rules_rust/rust/private/rust_analyzer_detect_sysroot.rust_analyzer_toolchain.json"
65     );
66     let toolchain_info: HashMap<String, String> =
67         serde_json::from_str(&std::fs::read_to_string(path)?)?;
68 
69     let sysroot_src = &toolchain_info["sysroot_src"];
70     let sysroot = &toolchain_info["sysroot"];
71 
72     let rust_project = rust_project::generate_rust_project(sysroot, sysroot_src, &crate_specs)?;
73 
74     rust_project::write_rust_project(
75         rust_project_path.as_ref(),
76         execution_root.as_ref(),
77         output_base.as_ref(),
78         &rust_project,
79     )?;
80 
81     Ok(())
82 }
83