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