From 14f2fffeb3de5f653c11694ee3c5e5d62aaa34ec Mon Sep 17 00:00:00 2001 From: Koby Hall <102518238+kobyhallx@users.noreply.github.com> Date: Wed, 13 Dec 2023 18:33:09 +0100 Subject: [PATCH] fix(lsp): package resolution on save (#3794) # Description ## Problem\* ## Summary\* While saving file - procedure of compiling package should be applied to single package rather than all packages available in workspace. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- tooling/lsp/src/notifications/mod.rs | 22 +++++++--------------- tooling/nargo_toml/src/lib.rs | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/tooling/lsp/src/notifications/mod.rs b/tooling/lsp/src/notifications/mod.rs index a3f2fdde3d..876ff157c0 100644 --- a/tooling/lsp/src/notifications/mod.rs +++ b/tooling/lsp/src/notifications/mod.rs @@ -2,7 +2,7 @@ use std::ops::ControlFlow; use async_lsp::{ErrorCode, LanguageClient, ResponseError}; use nargo::prepare_package; -use nargo_toml::{find_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use nargo_toml::{find_file_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_driver::{check_crate, NOIR_ARTIFACT_VERSION_STRING}; use noirc_errors::{DiagnosticKind, FileDiagnostic}; @@ -69,29 +69,21 @@ pub(super) fn on_did_save_text_document( } }; - let root_path = match &state.root_path { - Some(root) => root, - None => { - return ControlFlow::Break(Err(ResponseError::new( - ErrorCode::REQUEST_FAILED, - "Could not find project root", - ) - .into())); - } - }; + let package_root = find_file_manifest(file_path.as_path()); - let toml_path = match find_package_manifest(root_path, &file_path) { - Ok(toml_path) => toml_path, - Err(err) => { + let toml_path = match package_root { + Some(toml_path) => toml_path, + None => { // If we cannot find a manifest, we log a warning but return no diagnostics // We can reconsider this when we can build a file without the need for a Nargo.toml file to resolve deps let _ = state.client.log_message(LogMessageParams { typ: MessageType::WARNING, - message: format!("{err}"), + message: format!("Nargo.toml not found for file: {:}", file_path.display()), }); return ControlFlow::Continue(()); } }; + let workspace = match resolve_workspace_from_toml( &toml_path, PackageSelection::All, diff --git a/tooling/nargo_toml/src/lib.rs b/tooling/nargo_toml/src/lib.rs index 31426ee4ee..56024f8ed4 100644 --- a/tooling/nargo_toml/src/lib.rs +++ b/tooling/nargo_toml/src/lib.rs @@ -24,6 +24,27 @@ mod semver; pub use errors::ManifestError; use git::clone_git_repo; +/// Searches for a `Nargo.toml` file in the current directory and all parent directories. +/// For example, if the current directory is `/workspace/package/src`, then this function +/// will search for a `Nargo.toml` file in +/// * `/workspace/package/src`, +/// * `/workspace/package`, +/// * `/workspace`. +/// +/// Returns the [PathBuf] of the `Nargo.toml` file if found, otherwise returns None. +/// +/// It will return innermost `Nargo.toml` file, which is the one closest to the current directory. +/// For example, if the current directory is `/workspace/package/src`, then this function +/// will return the `Nargo.toml` file in `/workspace/package/Nargo.toml` +pub fn find_file_manifest(current_path: &Path) -> Option { + for path in current_path.ancestors() { + if let Ok(toml_path) = get_package_manifest(path) { + return Some(toml_path); + } + } + None +} + /// Returns the [PathBuf] of the directory containing the `Nargo.toml` by searching from `current_path` to the root of its [Path]. /// /// Returns a [ManifestError] if no parent directories of `current_path` contain a manifest file.