mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Auto merge of #13128 - Veykril:invocation-strategy, r=Veykril
Implement invocation strategy config Fixes https://github.com/rust-lang/rust-analyzer/issues/10793 This allows to change how we run build scripts (and `checkOnSave`), exposing two configs: - `once`: run the specified command once in the project root (the working dir of the server) - `per_workspace`: run the specified command per workspace in the corresponding workspace This also applies to `checkOnSave` likewise, though `once_in_root` is useless there currently, due to https://github.com/rust-lang/cargo/issues/11007
This commit is contained in:
commit
a77ac93b2a
9 changed files with 471 additions and 207 deletions
|
@ -2,7 +2,7 @@
|
|||
//! metadata` or `rust-project.json`) into representation stored in the salsa
|
||||
//! database -- `CrateGraph`.
|
||||
|
||||
use std::{collections::VecDeque, fmt, fs, process::Command};
|
||||
use std::{collections::VecDeque, fmt, fs, process::Command, sync::Arc};
|
||||
|
||||
use anyhow::{format_err, Context, Result};
|
||||
use base_db::{
|
||||
|
@ -21,8 +21,8 @@ use crate::{
|
|||
cfg_flag::CfgFlag,
|
||||
rustc_cfg,
|
||||
sysroot::SysrootCrate,
|
||||
utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, Package, ProjectJson, ProjectManifest,
|
||||
Sysroot, TargetKind, WorkspaceBuildScripts,
|
||||
utf8_stdout, CargoConfig, CargoWorkspace, InvocationStrategy, ManifestPath, Package,
|
||||
ProjectJson, ProjectManifest, Sysroot, TargetKind, WorkspaceBuildScripts,
|
||||
};
|
||||
|
||||
/// A set of cfg-overrides per crate.
|
||||
|
@ -303,6 +303,7 @@ impl ProjectWorkspace {
|
|||
Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
|
||||
}
|
||||
|
||||
/// Runs the build scripts for this [`ProjectWorkspace`].
|
||||
pub fn run_build_scripts(
|
||||
&self,
|
||||
config: &CargoConfig,
|
||||
|
@ -310,9 +311,13 @@ impl ProjectWorkspace {
|
|||
) -> Result<WorkspaceBuildScripts> {
|
||||
match self {
|
||||
ProjectWorkspace::Cargo { cargo, toolchain, .. } => {
|
||||
WorkspaceBuildScripts::run(config, cargo, progress, toolchain).with_context(|| {
|
||||
format!("Failed to run build scripts for {}", &cargo.workspace_root().display())
|
||||
})
|
||||
WorkspaceBuildScripts::run_for_workspace(config, cargo, progress, toolchain)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to run build scripts for {}",
|
||||
&cargo.workspace_root().display()
|
||||
)
|
||||
})
|
||||
}
|
||||
ProjectWorkspace::Json { .. } | ProjectWorkspace::DetachedFiles { .. } => {
|
||||
Ok(WorkspaceBuildScripts::default())
|
||||
|
@ -320,6 +325,47 @@ impl ProjectWorkspace {
|
|||
}
|
||||
}
|
||||
|
||||
/// Runs the build scripts for the given [`ProjectWorkspace`]s. Depending on the invocation
|
||||
/// strategy this may run a single build process for all project workspaces.
|
||||
pub fn run_all_build_scripts(
|
||||
workspaces: &[ProjectWorkspace],
|
||||
config: &CargoConfig,
|
||||
progress: &dyn Fn(String),
|
||||
) -> Vec<Result<WorkspaceBuildScripts>> {
|
||||
if let InvocationStrategy::PerWorkspace = config.invocation_strategy {
|
||||
return workspaces.iter().map(|it| it.run_build_scripts(config, progress)).collect();
|
||||
}
|
||||
|
||||
let cargo_ws: Vec<_> = workspaces
|
||||
.iter()
|
||||
.filter_map(|it| match it {
|
||||
ProjectWorkspace::Cargo { cargo, .. } => Some(cargo),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
let ref mut outputs = match WorkspaceBuildScripts::run_once(config, &cargo_ws, progress) {
|
||||
Ok(it) => Ok(it.into_iter()),
|
||||
// io::Error is not Clone?
|
||||
Err(e) => Err(Arc::new(e)),
|
||||
};
|
||||
|
||||
workspaces
|
||||
.iter()
|
||||
.map(|it| match it {
|
||||
ProjectWorkspace::Cargo { cargo, .. } => match outputs {
|
||||
Ok(outputs) => Ok(outputs.next().unwrap()),
|
||||
Err(e) => Err(e.clone()).with_context(|| {
|
||||
format!(
|
||||
"Failed to run build scripts for {}",
|
||||
&cargo.workspace_root().display()
|
||||
)
|
||||
}),
|
||||
},
|
||||
_ => Ok(WorkspaceBuildScripts::default()),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn set_build_scripts(&mut self, bs: WorkspaceBuildScripts) {
|
||||
match self {
|
||||
ProjectWorkspace::Cargo { build_scripts, .. } => *build_scripts = bs,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue