Run flycheck only on crate if target is binary.

This commit is contained in:
Ali Bektas 2024-08-20 18:13:22 +02:00
parent b02c214132
commit ffc3bfe435
3 changed files with 58 additions and 27 deletions

View file

@ -118,14 +118,14 @@ impl FlycheckHandle {
} }
/// Schedule a re-start of the cargo check worker to do a workspace wide check. /// Schedule a re-start of the cargo check worker to do a workspace wide check.
pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) { pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>, target: Option<String>) {
self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap(); self.sender.send(StateChange::Restart { package: None, saved_file, target }).unwrap();
} }
/// Schedule a re-start of the cargo check worker to do a package wide check. /// Schedule a re-start of the cargo check worker to do a package wide check.
pub(crate) fn restart_for_package(&self, package: String) { pub(crate) fn restart_for_package(&self, package: String, target: Option<String>) {
self.sender self.sender
.send(StateChange::Restart { package: Some(package), saved_file: None }) .send(StateChange::Restart { package: Some(package), saved_file: None, target })
.unwrap(); .unwrap();
} }
@ -183,7 +183,7 @@ pub(crate) enum Progress {
} }
enum StateChange { enum StateChange {
Restart { package: Option<String>, saved_file: Option<AbsPathBuf> }, Restart { package: Option<String>, saved_file: Option<AbsPathBuf>, target: Option<String> },
Cancel, Cancel,
} }
@ -271,7 +271,7 @@ impl FlycheckActor {
tracing::debug!(flycheck_id = self.id, "flycheck cancelled"); tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
self.cancel_check_process(); self.cancel_check_process();
} }
Event::RequestStateChange(StateChange::Restart { package, saved_file }) => { Event::RequestStateChange(StateChange::Restart { package, saved_file, target }) => {
// Cancel the previously spawned process // Cancel the previously spawned process
self.cancel_check_process(); self.cancel_check_process();
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) { while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
@ -281,11 +281,14 @@ impl FlycheckActor {
} }
} }
let command = let command = match self.check_command(
match self.check_command(package.as_deref(), saved_file.as_deref()) { package.as_deref(),
Some(c) => c, saved_file.as_deref(),
None => continue, target.as_deref(),
}; ) {
Some(c) => c,
None => continue,
};
let formatted_command = format!("{command:?}"); let formatted_command = format!("{command:?}");
tracing::debug!(?command, "will restart flycheck"); tracing::debug!(?command, "will restart flycheck");
@ -381,6 +384,7 @@ impl FlycheckActor {
&self, &self,
package: Option<&str>, package: Option<&str>,
saved_file: Option<&AbsPath>, saved_file: Option<&AbsPath>,
bin_target: Option<&str>,
) -> Option<Command> { ) -> Option<Command> {
match &self.config { match &self.config {
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => { FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
@ -396,6 +400,10 @@ impl FlycheckActor {
None => cmd.arg("--workspace"), None => cmd.arg("--workspace"),
}; };
if let Some(tgt) = bin_target {
cmd.arg("--bin").arg(tgt);
}
cmd.arg(if *ansi_color_output { cmd.arg(if *ansi_color_output {
"--message-format=json-diagnostic-rendered-ansi" "--message-format=json-diagnostic-rendered-ansi"
} else { } else {

View file

@ -20,6 +20,7 @@ use crate::{
lsp_ext::{self, RunFlycheckParams}, lsp_ext::{self, RunFlycheckParams},
mem_docs::DocumentData, mem_docs::DocumentData,
reload, reload,
target_spec::TargetSpec,
}; };
pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> { pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> {
@ -185,7 +186,7 @@ pub(crate) fn handle_did_save_text_document(
} else if state.config.check_on_save() { } else if state.config.check_on_save() {
// No specific flycheck was triggered, so let's trigger all of them. // No specific flycheck was triggered, so let's trigger all of them.
for flycheck in state.flycheck.iter() { for flycheck in state.flycheck.iter() {
flycheck.restart_workspace(None); flycheck.restart_workspace(None, None);
} }
} }
Ok(()) Ok(())
@ -287,16 +288,33 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
let world = state.snapshot(); let world = state.snapshot();
let mut updated = false; let mut updated = false;
let task = move || -> std::result::Result<(), ide::Cancelled> { let task = move || -> std::result::Result<(), ide::Cancelled> {
// Trigger flychecks for all workspaces that depend on the saved file // Is the target binary? If so we let flycheck run only for the workspace that contains the crate.
// Crates containing or depending on the saved file let target_is_bin = TargetSpec::for_file(&world, file_id)?.and_then(|x| {
let crate_ids: Vec<_> = world if x.target_kind() == project_model::TargetKind::Bin {
.analysis return match x {
.crates_for(file_id)? TargetSpec::Cargo(c) => Some(c.target),
.into_iter() TargetSpec::ProjectJson(p) => Some(p.label),
.flat_map(|id| world.analysis.transitive_rev_deps(id)) };
.flatten() }
.unique()
.collect(); None
});
let crate_ids = if target_is_bin.is_some() {
// Trigger flychecks for the only workspace which the binary crate belongs to
world.analysis.crates_for(file_id)?.into_iter().unique().collect::<Vec<_>>()
} else {
// Trigger flychecks for all workspaces that depend on the saved file
// Crates containing or depending on the saved file
world
.analysis
.crates_for(file_id)?
.into_iter()
.flat_map(|id| world.analysis.transitive_rev_deps(id))
.flatten()
.unique()
.collect::<Vec<_>>()
};
let crate_root_paths: Vec<_> = crate_ids let crate_root_paths: Vec<_> = crate_ids
.iter() .iter()
@ -347,8 +365,11 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
if id == flycheck.id() { if id == flycheck.id() {
updated = true; updated = true;
match package.filter(|_| !world.config.flycheck_workspace()) { match package.filter(|_| !world.config.flycheck_workspace()) {
Some(package) => flycheck.restart_for_package(package), Some(package) => {
None => flycheck.restart_workspace(saved_file.clone()), flycheck.restart_for_package(package, target_is_bin.clone())
}
None => flycheck
.restart_workspace(saved_file.clone(), target_is_bin.clone()),
} }
continue; continue;
} }
@ -357,7 +378,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
// No specific flycheck was triggered, so let's trigger all of them. // No specific flycheck was triggered, so let's trigger all of them.
if !updated { if !updated {
for flycheck in world.flycheck.iter() { for flycheck in world.flycheck.iter() {
flycheck.restart_workspace(saved_file.clone()); flycheck.restart_workspace(saved_file.clone(), None);
} }
} }
Ok(()) Ok(())
@ -399,7 +420,7 @@ pub(crate) fn handle_run_flycheck(
} }
// No specific flycheck was triggered, so let's trigger all of them. // No specific flycheck was triggered, so let's trigger all of them.
for flycheck in state.flycheck.iter() { for flycheck in state.flycheck.iter() {
flycheck.restart_workspace(None); flycheck.restart_workspace(None, None);
} }
Ok(()) Ok(())
} }

View file

@ -406,7 +406,9 @@ impl GlobalState {
if became_quiescent { if became_quiescent {
if self.config.check_on_save() { if self.config.check_on_save() {
// Project has loaded properly, kick off initial flycheck // Project has loaded properly, kick off initial flycheck
self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None)); self.flycheck
.iter()
.for_each(|flycheck| flycheck.restart_workspace(None, None));
} }
if self.config.prefill_caches() { if self.config.prefill_caches() {
self.prime_caches_queue.request_op("became quiescent".to_owned(), ()); self.prime_caches_queue.request_op("became quiescent".to_owned(), ());