diff --git a/crates/ruff_server/src/session/settings.rs b/crates/ruff_server/src/session/settings.rs index 924ae195c7ac54..1819dde697b98b 100644 --- a/crates/ruff_server/src/session/settings.rs +++ b/crates/ruff_server/src/session/settings.rs @@ -1,7 +1,15 @@ -use std::{ffi::OsString, ops::Deref, path::PathBuf, str::FromStr}; +use std::{ops::Deref, path::Path, str::FromStr}; use lsp_types::Url; -use ruff_linter::{line_width::LineLength, RuleSelector}; +use ruff_linter::{ + fs::normalize_path_to, + line_width::LineLength, + settings::types::{FilePattern, PreviewMode}, + RuleSelector, +}; +use ruff_workspace::configuration::{ + Configuration, FormatConfiguration, LintConfiguration, RuleSelection, +}; use rustc_hash::FxHashMap; use serde::Deserialize; @@ -36,7 +44,7 @@ pub(crate) struct ResolvedEditorSettings { select: Option>, extend_select: Option>, ignore: Option>, - exclude: Option>, + exclude: Option>, line_length: Option, } @@ -248,14 +256,7 @@ impl ResolvedClientSettings { .collect() }), exclude: Self::resolve_optional(all_settings, |settings| { - Some( - settings - .exclude - .as_ref()? - .iter() - .map(|path| PathBuf::from(OsString::from(path))) - .collect(), - ) + Some(settings.exclude.as_ref()?.clone()) }), line_length: Self::resolve_optional(all_settings, |settings| settings.line_length), }, @@ -309,6 +310,56 @@ impl ResolvedClientSettings { } } +impl ResolvedEditorSettings { + pub(crate) fn resolve( + &self, + project_root: &Path, + project_configuration: Configuration, + ) -> crate::Result { + let Self { + format_preview, + lint_preview, + select, + extend_select, + ignore, + exclude, + line_length, + } = self.clone(); + + let editor_configuration = Configuration { + lint: LintConfiguration { + preview: lint_preview.map(PreviewMode::from), + rule_selections: vec![RuleSelection { + select, + extend_select: extend_select.unwrap_or_default(), + ignore: ignore.unwrap_or_default(), + ..Default::default() + }], + ..Default::default() + }, + format: FormatConfiguration { + preview: format_preview.map(PreviewMode::from), + ..Default::default() + }, + exclude: exclude.map(|exclude| { + exclude + .into_iter() + .map(|pattern| { + let absolute = normalize_path_to(&pattern, project_root); + FilePattern::User(pattern, absolute) + }) + .collect() + }), + line_length, + ..Default::default() + }; + + let configuration = editor_configuration.combine(project_configuration); + + configuration.into_settings(project_root) + } +} + impl Default for InitializationOptions { fn default() -> Self { Self::GlobalOnly { settings: None } diff --git a/crates/ruff_server/src/session/workspace/ruff_settings.rs b/crates/ruff_server/src/session/workspace/ruff_settings.rs index 70c56aafa95136..219bfe3c6c450a 100644 --- a/crates/ruff_server/src/session/workspace/ruff_settings.rs +++ b/crates/ruff_server/src/session/workspace/ruff_settings.rs @@ -40,12 +40,15 @@ impl std::fmt::Display for RuffSettings { impl RuffSettings { pub(crate) fn resolve( - linter: ruff_linter::settings::LinterSettings, - formatter: ruff_workspace::FormatterSettings, + project_root: &Path, + configuration: ruff_workspace::configuration::Configuration, editor_settings: &ResolvedEditorSettings, - ) -> Self { - // TODO(jane): impl resolution - Self { linter, formatter } + ) -> crate::Result { + let settings = editor_settings.resolve(project_root, configuration)?; + Ok(Self { + linter: settings.linter, + formatter: settings.formatter, + }) } pub(crate) fn linter(&self) -> &ruff_linter::settings::LinterSettings { @@ -68,21 +71,18 @@ impl RuffSettingsIndex { .map(DirEntry::into_path) { if let Some(pyproject) = settings_toml(&directory).ok().flatten() { - let Ok(settings) = ruff_workspace::resolver::resolve_root_settings( + let Ok(configuration) = ruff_workspace::resolver::resolve_configuration( &pyproject, Relativity::Parent, &LSPConfigTransformer, ) else { continue; }; - index.insert( - directory, - Arc::new(RuffSettings::resolve( - settings.linter, - settings.formatter, - editor_settings, - )), - ); + let Ok(settings) = RuffSettings::resolve(root, configuration, editor_settings) + else { + continue; + }; + index.insert(directory, Arc::new(settings)); } } diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index 7ccd78f690c5db..ff1ce41c95357b 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -240,7 +240,7 @@ pub trait ConfigurationTransformer: Sync { // configuration file extends another in the same path, we'll re-parse the same // file at least twice (possibly more than twice, since we'll also parse it when // resolving the "default" configuration). -fn resolve_configuration( +pub fn resolve_configuration( pyproject: &Path, relativity: Relativity, transformer: &dyn ConfigurationTransformer,