Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow cargo check to run on only the current package #16510

Merged
merged 1 commit into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 17 additions & 8 deletions crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ impl FlycheckHandle {
FlycheckHandle { id, sender, _thread: thread }
}

/// Schedule a re-start of the cargo check worker.
pub fn restart(&self) {
self.sender.send(StateChange::Restart).unwrap();
/// Schedule a re-start of the cargo check worker to do a workspace wide check.
pub fn restart_workspace(&self) {
self.sender.send(StateChange::Restart(None)).unwrap();
}

/// Schedule a re-start of the cargo check worker to do a package wide check.
pub fn restart_for_package(&self, package: String) {
self.sender.send(StateChange::Restart(Some(package))).unwrap();
}

/// Stop this cargo check worker.
Expand Down Expand Up @@ -153,7 +158,7 @@ pub enum Progress {
}

enum StateChange {
Restart,
Restart(Option<String>),
Cancel,
}

Expand Down Expand Up @@ -213,7 +218,7 @@ impl FlycheckActor {
tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
self.cancel_check_process();
}
Event::RequestStateChange(StateChange::Restart) => {
Event::RequestStateChange(StateChange::Restart(package)) => {
// Cancel the previously spawned process
self.cancel_check_process();
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
Expand All @@ -223,7 +228,7 @@ impl FlycheckActor {
}
}

let command = self.check_command();
let command = self.check_command(package.as_deref());
let formatted_command = format!("{:?}", command);

tracing::debug!(?command, "will restart flycheck");
Expand Down Expand Up @@ -297,7 +302,7 @@ impl FlycheckActor {
}
}

fn check_command(&self) -> Command {
fn check_command(&self, package: Option<&str>) -> Command {
let (mut cmd, args) = match &self.config {
FlycheckConfig::CargoCommand {
command,
Expand All @@ -314,7 +319,11 @@ impl FlycheckActor {
let mut cmd = Command::new(toolchain::cargo());
cmd.arg(command);
cmd.current_dir(&self.root);
cmd.arg("--workspace");

match package {
Some(pkg) => cmd.arg("-p").arg(pkg),
None => cmd.arg("--workspace"),
};

cmd.arg(if *ansi_color_output {
"--message-format=json-diagnostic-rendered-ansi"
Expand Down
7 changes: 7 additions & 0 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ config_data! {
///
/// Aliased as `"checkOnSave.targets"`.
check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = "null",
/// Whether `--workspace` should be passed to `cargo check`.
/// If false, `-p <package>` will be passed instead.
check_workspace: bool = "true",

/// Toggles the additional completions that automatically add imports when completed.
/// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
Expand Down Expand Up @@ -1323,6 +1326,10 @@ impl Config {
}
}

pub fn flycheck_workspace(&self) -> bool {
self.data.check_workspace
}

pub fn flycheck(&self) -> FlycheckConfig {
match &self.data.check_overrideCommand {
Some(args) if !args.is_empty() => {
Expand Down
49 changes: 31 additions & 18 deletions crates/rust-analyzer/src/handlers/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub(crate) fn handle_did_save_text_document(
} else if state.config.check_on_save() {
// No specific flycheck was triggered, so let's trigger all of them.
for flycheck in state.flycheck.iter() {
flycheck.restart();
flycheck.restart_workspace();
}
}
Ok(())
Expand Down Expand Up @@ -281,35 +281,48 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
let crate_root_paths: Vec<_> = crate_root_paths.iter().map(Deref::deref).collect();

// Find all workspaces that have at least one target containing the saved file
let workspace_ids = world.workspaces.iter().enumerate().filter(|(_, ws)| match ws {
project_model::ProjectWorkspace::Cargo { cargo, .. } => {
cargo.packages().any(|pkg| {
cargo[pkg]
.targets
.iter()
.any(|&it| crate_root_paths.contains(&cargo[it].root.as_path()))
})
}
project_model::ProjectWorkspace::Json { project, .. } => {
project.crates().any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c))
}
project_model::ProjectWorkspace::DetachedFiles { .. } => false,
let workspace_ids = world.workspaces.iter().enumerate().filter_map(|(idx, ws)| {
let package = match ws {
project_model::ProjectWorkspace::Cargo { cargo, .. } => {
cargo.packages().find_map(|pkg| {
let has_target_with_root = cargo[pkg]
.targets
.iter()
.any(|&it| crate_root_paths.contains(&cargo[it].root.as_path()));
has_target_with_root.then(|| cargo[pkg].name.clone())
})
}
project_model::ProjectWorkspace::Json { project, .. } => {
if !project
.crates()
.any(|(c, _)| crate_ids.iter().any(|&crate_id| crate_id == c))
{
return None;
}
None
}
project_model::ProjectWorkspace::DetachedFiles { .. } => return None,
};
Some((idx, package))
});

// Find and trigger corresponding flychecks
for flycheck in world.flycheck.iter() {
for (id, _) in workspace_ids.clone() {
for (id, package) in workspace_ids.clone() {
if id == flycheck.id() {
updated = true;
flycheck.restart();
match package.filter(|_| !world.config.flycheck_workspace()) {
Some(package) => flycheck.restart_for_package(package),
None => flycheck.restart_workspace(),
}
continue;
}
}
}
// No specific flycheck was triggered, so let's trigger all of them.
if !updated {
for flycheck in world.flycheck.iter() {
flycheck.restart();
flycheck.restart_workspace();
}
}
Ok(())
Expand Down Expand Up @@ -351,7 +364,7 @@ pub(crate) fn handle_run_flycheck(
}
// No specific flycheck was triggered, so let's trigger all of them.
for flycheck in state.flycheck.iter() {
flycheck.restart();
flycheck.restart_workspace();
}
Ok(())
}
2 changes: 1 addition & 1 deletion crates/rust-analyzer/src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ impl GlobalState {
if became_quiescent {
if self.config.check_on_save() {
// Project has loaded properly, kick off initial flycheck
self.flycheck.iter().for_each(FlycheckHandle::restart);
self.flycheck.iter().for_each(FlycheckHandle::restart_workspace);
}
if self.config.prefill_caches() {
self.prime_caches_queue.request_op("became quiescent".to_string(), ());
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-analyzer/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ impl GlobalState {
let mut crate_graph_file_dependencies = FxHashSet::default();

let mut load = |path: &AbsPath| {
let _p = tracing::span!(tracing::Level::INFO, "switch_workspaces::load").entered();
let _p = tracing::span!(tracing::Level::DEBUG, "switch_workspaces::load").entered();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's up to you, but this change means that hprof won't pick up on this span.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My base logs became completely useless due to that trace hence the change. Should be fine not to have that included in hprof

let vfs_path = vfs::VfsPath::from(path.to_path_buf());
crate_graph_file_dependencies.insert(vfs_path.clone());
match vfs.file_id(&vfs_path) {
Expand Down
6 changes: 6 additions & 0 deletions docs/user/generated_config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets,

Aliased as `"checkOnSave.targets"`.
--
[[rust-analyzer.check.workspace]]rust-analyzer.check.workspace (default: `true`)::
+
--
Whether `--workspace` should be passed to `cargo check`.
If false, `-p <package>` will be passed instead.
--
[[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
+
--
Expand Down
5 changes: 5 additions & 0 deletions editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,11 @@
}
]
},
"rust-analyzer.check.workspace": {
"markdownDescription": "Whether `--workspace` should be passed to `cargo check`.\nIf false, `-p <package>` will be passed instead.",
"default": true,
"type": "boolean"
},
"rust-analyzer.completion.autoimport.enable": {
"markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",
"default": true,
Expand Down