Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/workspace.rs')
-rw-r--r--crates/project-model/src/workspace.rs58
1 files changed, 52 insertions, 6 deletions
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 9b0a261703..01180fcf4c 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -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,