blob: 53cf0bf72246a8ce240f2d2cd74fcde340b94616 [file] [log] [blame]
Adam Snaider1c095c92023-07-08 02:09:58 -04001use std::collections::HashMap;
Brian Silvermancc09f182022-03-09 15:40:20 -08002use std::path::Path;
3use std::process::Command;
4
5use anyhow::anyhow;
6use runfiles::Runfiles;
7
8mod aquery;
9mod rust_project;
10
11const SYSROOT_SRC_FILE_RUNFILES_PREFIX: &str = "rules_rust";
12
13pub fn generate_crate_info(
14 bazel: impl AsRef<Path>,
15 workspace: impl AsRef<Path>,
16 rules_rust: impl AsRef<str>,
17 targets: &[String],
18) -> anyhow::Result<()> {
19 log::debug!("Building rust_analyzer_crate_spec files for {:?}", targets);
20
21 let output = Command::new(bazel.as_ref())
22 .current_dir(workspace.as_ref())
23 .arg("build")
24 .arg(format!(
25 "--aspects={}//rust:defs.bzl%rust_analyzer_aspect",
26 rules_rust.as_ref()
27 ))
28 .arg("--output_groups=rust_analyzer_crate_spec")
29 .args(targets)
30 .output()?;
31
32 if !output.status.success() {
33 return Err(anyhow!(
34 "bazel build failed:({})\n{}",
35 output.status,
36 String::from_utf8_lossy(&output.stderr)
37 ));
38 }
39
40 Ok(())
41}
42
43pub fn write_rust_project(
44 bazel: impl AsRef<Path>,
45 workspace: impl AsRef<Path>,
46 rules_rust_name: &impl AsRef<str>,
47 targets: &[String],
48 execution_root: impl AsRef<Path>,
Brian Silverman5f6f2762022-08-13 19:30:05 -070049 output_base: impl AsRef<Path>,
Brian Silvermancc09f182022-03-09 15:40:20 -080050 rust_project_path: impl AsRef<Path>,
51) -> anyhow::Result<()> {
52 let crate_specs = aquery::get_crate_specs(
53 bazel.as_ref(),
54 workspace.as_ref(),
55 execution_root.as_ref(),
56 targets,
57 rules_rust_name.as_ref(),
58 )?;
59
60 let workspace_name = match rules_rust_name.as_ref().trim_start_matches('@') {
61 "" => SYSROOT_SRC_FILE_RUNFILES_PREFIX,
62 s => s,
63 };
Adam Snaider1c095c92023-07-08 02:09:58 -040064 let toolchain_info_path = format!(
65 "{workspace_name}/rust/private/rust_analyzer_detect_sysroot.rust_analyzer_toolchain.json"
Brian Silvermancc09f182022-03-09 15:40:20 -080066 );
67 let r = Runfiles::create()?;
Adam Snaider1c095c92023-07-08 02:09:58 -040068 let path = r.rlocation(toolchain_info_path);
69 let toolchain_info: HashMap<String, String> =
70 serde_json::from_str(&std::fs::read_to_string(path)?)?;
Brian Silvermancc09f182022-03-09 15:40:20 -080071
Adam Snaider1c095c92023-07-08 02:09:58 -040072 let sysroot_src = &toolchain_info["sysroot_src"];
73 let sysroot = &toolchain_info["sysroot"];
74
75 let rust_project = rust_project::generate_rust_project(sysroot, sysroot_src, &crate_specs)?;
Brian Silvermancc09f182022-03-09 15:40:20 -080076
77 rust_project::write_rust_project(
78 rust_project_path.as_ref(),
79 execution_root.as_ref(),
Brian Silverman5f6f2762022-08-13 19:30:05 -070080 output_base.as_ref(),
Brian Silvermancc09f182022-03-09 15:40:20 -080081 &rust_project,
82 )?;
83
84 Ok(())
85}