diff --git a/crates/ruff_server/src/session/workspace/configuration.rs b/crates/ruff_server/src/session/workspace/configuration.rs index 8818a1e615..46eb8491a3 100644 --- a/crates/ruff_server/src/session/workspace/configuration.rs +++ b/crates/ruff_server/src/session/workspace/configuration.rs @@ -1,6 +1,11 @@ +use anyhow::anyhow; use lsp_types::Url; -use ruff_workspace::resolver::ConfigurationTransformer; -use std::{collections::BTreeMap, path::PathBuf, sync::Arc}; +use ruff_workspace::resolver::{ConfigurationTransformer, Relativity}; +use std::{ + collections::BTreeMap, + path::{Path, PathBuf}, + sync::Arc, +}; #[derive(Default)] pub(crate) struct RuffConfiguration { @@ -16,13 +21,45 @@ pub(super) struct ConfigurationIndex { } impl ConfigurationIndex { - pub(super) fn get_or_insert(&mut self, path: &Url) -> Arc { - todo!("impl"); + pub(super) fn get_or_insert(&mut self, document_url: &Url) -> Arc { + let document_path = document_url + .to_file_path() + .expect("document URL should be a valid path"); + let folder = document_path + .parent() + .expect("document URL should be a file path and have a parent"); + if let Some(config) = self.index.get(folder) { + return config.clone(); + } + + let config = Arc::new(Self::find_configuration_at_path(folder).unwrap_or_else(|err| { + tracing::error!("The following error occurred when trying to find a configuration file at `{}`:\n{err}", document_path.display()); + tracing::error!("Falling back to default configuration for `{}`", document_path.display()); + RuffConfiguration::default() + })); + + self.index.insert(folder.to_path_buf(), config.clone()); + + config } pub(super) fn clear(&mut self) { self.index.clear(); } + + fn find_configuration_at_path(folder: &Path) -> crate::Result { + let pyproject = ruff_workspace::pyproject::find_settings_toml(folder)? + .ok_or_else(|| anyhow!("No pyproject.toml/ruff.toml/.ruff.toml file was found"))?; + let settings = ruff_workspace::resolver::resolve_root_settings( + &pyproject, + Relativity::Parent, + &LSPConfigTransformer, + )?; + Ok(RuffConfiguration { + linter: settings.linter, + formatter: settings.formatter, + }) + } } struct LSPConfigTransformer;