Skip to content

Commit a77ac93

Browse files
committed
Auto merge of rust-lang#13128 - Veykril:invocation-strategy, r=Veykril
Implement invocation strategy config Fixes rust-lang/rust-analyzer#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 rust-lang/cargo#11007
2 parents 82ac6f7 + 4673236 commit a77ac93

File tree

9 files changed

+447
-183
lines changed

9 files changed

+447
-183
lines changed

crates/flycheck/src/lib.rs

+35-19
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ pub use cargo_metadata::diagnostic::{
2121
DiagnosticSpanMacroExpansion,
2222
};
2323

24+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
25+
pub enum InvocationStrategy {
26+
Once,
27+
#[default]
28+
PerWorkspace,
29+
}
30+
2431
#[derive(Clone, Debug, PartialEq, Eq)]
2532
pub enum FlycheckConfig {
2633
CargoCommand {
@@ -32,11 +39,13 @@ pub enum FlycheckConfig {
3239
features: Vec<String>,
3340
extra_args: Vec<String>,
3441
extra_env: FxHashMap<String, String>,
42+
invocation_strategy: InvocationStrategy,
3543
},
3644
CustomCommand {
3745
command: String,
3846
args: Vec<String>,
3947
extra_env: FxHashMap<String, String>,
48+
invocation_strategy: InvocationStrategy,
4049
},
4150
}
4251

@@ -136,11 +145,15 @@ enum Restart {
136145
No,
137146
}
138147

148+
/// A [`FlycheckActor`] is a single check instance of a workspace.
139149
struct FlycheckActor {
150+
/// The workspace id of this flycheck instance.
140151
id: usize,
141152
sender: Box<dyn Fn(Message) + Send>,
142153
config: FlycheckConfig,
143-
workspace_root: AbsPathBuf,
154+
/// Either the workspace root of the workspace we are flychecking,
155+
/// or the project root of the project.
156+
root: AbsPathBuf,
144157
/// CargoHandle exists to wrap around the communication needed to be able to
145158
/// run `cargo check` without blocking. Currently the Rust standard library
146159
/// doesn't provide a way to read sub-process output without blocking, so we
@@ -162,11 +175,13 @@ impl FlycheckActor {
162175
workspace_root: AbsPathBuf,
163176
) -> FlycheckActor {
164177
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
165-
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
178+
FlycheckActor { id, sender, config, root: workspace_root, cargo_handle: None }
166179
}
167-
fn progress(&self, progress: Progress) {
180+
181+
fn report_progress(&self, progress: Progress) {
168182
self.send(Message::Progress { id: self.id, progress });
169183
}
184+
170185
fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
171186
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
172187
if let Ok(msg) = inbox.try_recv() {
@@ -178,6 +193,7 @@ impl FlycheckActor {
178193
recv(check_chan.unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())),
179194
}
180195
}
196+
181197
fn run(mut self, inbox: Receiver<Restart>) {
182198
'event: while let Some(event) = self.next_event(&inbox) {
183199
match event {
@@ -203,10 +219,10 @@ impl FlycheckActor {
203219
"did restart flycheck"
204220
);
205221
self.cargo_handle = Some(cargo_handle);
206-
self.progress(Progress::DidStart);
222+
self.report_progress(Progress::DidStart);
207223
}
208224
Err(error) => {
209-
self.progress(Progress::DidFailToRestart(format!(
225+
self.report_progress(Progress::DidFailToRestart(format!(
210226
"Failed to run the following command: {:?} error={}",
211227
self.check_command(),
212228
error
@@ -226,17 +242,17 @@ impl FlycheckActor {
226242
self.check_command()
227243
);
228244
}
229-
self.progress(Progress::DidFinish(res));
245+
self.report_progress(Progress::DidFinish(res));
230246
}
231247
Event::CheckEvent(Some(message)) => match message {
232248
CargoMessage::CompilerArtifact(msg) => {
233-
self.progress(Progress::DidCheckCrate(msg.target.name));
249+
self.report_progress(Progress::DidCheckCrate(msg.target.name));
234250
}
235251

236252
CargoMessage::Diagnostic(msg) => {
237253
self.send(Message::AddDiagnostic {
238254
id: self.id,
239-
workspace_root: self.workspace_root.clone(),
255+
workspace_root: self.root.clone(),
240256
diagnostic: msg,
241257
});
242258
}
@@ -254,12 +270,12 @@ impl FlycheckActor {
254270
"did cancel flycheck"
255271
);
256272
cargo_handle.cancel();
257-
self.progress(Progress::DidCancel);
273+
self.report_progress(Progress::DidCancel);
258274
}
259275
}
260276

261277
fn check_command(&self) -> Command {
262-
let mut cmd = match &self.config {
278+
let (mut cmd, args, invocation_strategy) = match &self.config {
263279
FlycheckConfig::CargoCommand {
264280
command,
265281
target_triple,
@@ -269,12 +285,11 @@ impl FlycheckActor {
269285
extra_args,
270286
features,
271287
extra_env,
288+
invocation_strategy,
272289
} => {
273290
let mut cmd = Command::new(toolchain::cargo());
274291
cmd.arg(command);
275-
cmd.current_dir(&self.workspace_root);
276-
cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
277-
.arg(self.workspace_root.join("Cargo.toml").as_os_str());
292+
cmd.args(&["--workspace", "--message-format=json"]);
278293

279294
if let Some(target) = target_triple {
280295
cmd.args(&["--target", target.as_str()]);
@@ -293,18 +308,19 @@ impl FlycheckActor {
293308
cmd.arg(features.join(" "));
294309
}
295310
}
296-
cmd.args(extra_args);
297311
cmd.envs(extra_env);
298-
cmd
312+
(cmd, extra_args, invocation_strategy)
299313
}
300-
FlycheckConfig::CustomCommand { command, args, extra_env } => {
314+
FlycheckConfig::CustomCommand { command, args, extra_env, invocation_strategy } => {
301315
let mut cmd = Command::new(command);
302-
cmd.args(args);
303316
cmd.envs(extra_env);
304-
cmd
317+
(cmd, args, invocation_strategy)
305318
}
306319
};
307-
cmd.current_dir(&self.workspace_root);
320+
match invocation_strategy {
321+
InvocationStrategy::PerWorkspace => cmd.current_dir(&self.root),
322+
InvocationStrategy::Once => cmd.args(args),
323+
};
308324
cmd
309325
}
310326

0 commit comments

Comments
 (0)