Directly include Settings struct for the server (#16042)

## Summary

This PR refactors the `RuffSettings` struct to directly include the
resolved `Settings` instead of including the specific fields from it.
The server utilizes a lot of it already, so it makes sense to just
include the entire struct for simplicity.

### `Deref`

I implemented `Deref` on `RuffSettings` to return the `Settings` because
`RuffSettings` is now basically a wrapper around it with the config path
as the other field. This path field is only used for debugging
("printDebugInformation" command).
This commit is contained in:
Dhruv Manilawala 2025-02-10 10:20:01 +05:30 committed by GitHub
parent b54e390cb4
commit cc0a5dd14a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 37 additions and 76 deletions

View file

@ -27,15 +27,14 @@ pub(crate) fn fix_all(
encoding: PositionEncoding, encoding: PositionEncoding,
) -> crate::Result<Fixes> { ) -> crate::Result<Fixes> {
let source_kind = query.make_source_kind(); let source_kind = query.make_source_kind();
let settings = query.settings();
let file_resolver_settings = query.settings().file_resolver();
let document_path = query.file_path(); let document_path = query.file_path();
// If the document is excluded, return an empty list of fixes. // If the document is excluded, return an empty list of fixes.
let package = if let Some(document_path) = document_path.as_ref() { let package = if let Some(document_path) = document_path.as_ref() {
if is_document_excluded_for_linting( if is_document_excluded_for_linting(
document_path, document_path,
file_resolver_settings, &settings.file_resolver,
linter_settings, linter_settings,
query.text_document_language_id(), query.text_document_language_id(),
) { ) {
@ -71,7 +70,7 @@ pub(crate) fn fix_all(
&query.virtual_file_path(), &query.virtual_file_path(),
package, package,
flags::Noqa::Enabled, flags::Noqa::Enabled,
query.settings().unsafe_fixes(), settings.unsafe_fixes,
linter_settings, linter_settings,
&source_kind, &source_kind,
source_type, source_type,

View file

@ -67,16 +67,15 @@ pub(crate) fn check(
show_syntax_errors: bool, show_syntax_errors: bool,
) -> DiagnosticsMap { ) -> DiagnosticsMap {
let source_kind = query.make_source_kind(); let source_kind = query.make_source_kind();
let file_resolver_settings = query.settings().file_resolver(); let settings = query.settings();
let linter_settings = query.settings().linter();
let document_path = query.file_path(); let document_path = query.file_path();
// If the document is excluded, return an empty list of diagnostics. // If the document is excluded, return an empty list of diagnostics.
let package = if let Some(document_path) = document_path.as_ref() { let package = if let Some(document_path) = document_path.as_ref() {
if is_document_excluded_for_linting( if is_document_excluded_for_linting(
document_path, document_path,
file_resolver_settings, &settings.file_resolver,
linter_settings, &settings.linter,
query.text_document_language_id(), query.text_document_language_id(),
) { ) {
return DiagnosticsMap::default(); return DiagnosticsMap::default();
@ -86,7 +85,7 @@ pub(crate) fn check(
document_path document_path
.parent() .parent()
.expect("a path to a document should have a parent path"), .expect("a path to a document should have a parent path"),
&linter_settings.namespace_packages, &settings.linter.namespace_packages,
) )
.map(PackageRoot::root) .map(PackageRoot::root)
} else { } else {
@ -118,7 +117,7 @@ pub(crate) fn check(
&stylist, &stylist,
&indexer, &indexer,
&directives, &directives,
linter_settings, &settings.linter,
flags::Noqa::Enabled, flags::Noqa::Enabled,
&source_kind, &source_kind,
source_type, source_type,
@ -130,7 +129,7 @@ pub(crate) fn check(
&diagnostics, &diagnostics,
&locator, &locator,
indexer.comment_ranges(), indexer.comment_ranges(),
&linter_settings.external, &settings.linter.external,
&directives.noqa_line_for, &directives.noqa_line_for,
stylist.line_ending(), stylist.line_ending(),
); );

View file

@ -93,7 +93,7 @@ pub(super) fn fix_all_edit(
query: &DocumentQuery, query: &DocumentQuery,
encoding: PositionEncoding, encoding: PositionEncoding,
) -> crate::Result<Fixes> { ) -> crate::Result<Fixes> {
crate::fix::fix_all(query, query.settings().linter(), encoding) crate::fix::fix_all(query, &query.settings().linter, encoding)
} }
pub(super) fn resolve_edit_for_organize_imports( pub(super) fn resolve_edit_for_organize_imports(
@ -110,7 +110,7 @@ pub(super) fn organize_imports_edit(
query: &DocumentQuery, query: &DocumentQuery,
encoding: PositionEncoding, encoding: PositionEncoding,
) -> crate::Result<Fixes> { ) -> crate::Result<Fixes> {
let mut linter_settings = query.settings().linter().clone(); let mut linter_settings = query.settings().linter.clone();
linter_settings.rules = [ linter_settings.rules = [
Rule::UnsortedImports, // I001 Rule::UnsortedImports, // I001
Rule::MissingRequiredImport, // I002 Rule::MissingRequiredImport, // I002

View file

@ -82,15 +82,14 @@ fn format_text_document(
encoding: PositionEncoding, encoding: PositionEncoding,
is_notebook: bool, is_notebook: bool,
) -> Result<super::FormatResponse> { ) -> Result<super::FormatResponse> {
let file_resolver_settings = query.settings().file_resolver(); let settings = query.settings();
let formatter_settings = query.settings().formatter();
// If the document is excluded, return early. // If the document is excluded, return early.
if let Some(file_path) = query.file_path() { if let Some(file_path) = query.file_path() {
if is_document_excluded_for_formatting( if is_document_excluded_for_formatting(
&file_path, &file_path,
file_resolver_settings, &settings.file_resolver,
formatter_settings, &settings.formatter,
text_document.language_id(), text_document.language_id(),
) { ) {
return Ok(None); return Ok(None);
@ -98,7 +97,7 @@ fn format_text_document(
} }
let source = text_document.contents(); let source = text_document.contents();
let formatted = crate::format::format(text_document, query.source_type(), formatter_settings) let formatted = crate::format::format(text_document, query.source_type(), &settings.formatter)
.with_failure_code(lsp_server::ErrorCode::InternalError)?; .with_failure_code(lsp_server::ErrorCode::InternalError)?;
let Some(mut formatted) = formatted else { let Some(mut formatted) = formatted else {
return Ok(None); return Ok(None);

View file

@ -46,15 +46,14 @@ fn format_text_document_range(
query: &DocumentQuery, query: &DocumentQuery,
encoding: PositionEncoding, encoding: PositionEncoding,
) -> Result<super::FormatResponse> { ) -> Result<super::FormatResponse> {
let file_resolver_settings = query.settings().file_resolver(); let settings = query.settings();
let formatter_settings = query.settings().formatter();
// If the document is excluded, return early. // If the document is excluded, return early.
if let Some(file_path) = query.file_path() { if let Some(file_path) = query.file_path() {
if is_document_excluded_for_formatting( if is_document_excluded_for_formatting(
&file_path, &file_path,
file_resolver_settings, &settings.file_resolver,
formatter_settings, &settings.formatter,
text_document.language_id(), text_document.language_id(),
) { ) {
return Ok(None); return Ok(None);
@ -67,7 +66,7 @@ fn format_text_document_range(
let formatted_range = crate::format::format_range( let formatted_range = crate::format::format_range(
text_document, text_document,
query.source_type(), query.source_type(),
formatter_settings, &settings.formatter,
range, range,
) )
.with_failure_code(lsp_server::ErrorCode::InternalError)?; .with_failure_code(lsp_server::ErrorCode::InternalError)?;

View file

@ -1,4 +1,5 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ops::Deref;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@ -6,12 +7,11 @@ use std::sync::Arc;
use anyhow::Context; use anyhow::Context;
use ignore::{WalkBuilder, WalkState}; use ignore::{WalkBuilder, WalkState};
use ruff_linter::settings::types::UnsafeFixes;
use ruff_linter::{ use ruff_linter::{
display_settings, fs::normalize_path_to, settings::types::FilePattern, fs::normalize_path_to, settings::types::FilePattern, settings::types::PreviewMode,
settings::types::PreviewMode,
}; };
use ruff_workspace::resolver::match_exclusion; use ruff_workspace::resolver::match_exclusion;
use ruff_workspace::Settings;
use ruff_workspace::{ use ruff_workspace::{
configuration::{Configuration, FormatConfiguration, LintConfiguration, RuleSelection}, configuration::{Configuration, FormatConfiguration, LintConfiguration, RuleSelection},
pyproject::{find_user_settings_toml, settings_toml}, pyproject::{find_user_settings_toml, settings_toml},
@ -24,14 +24,16 @@ pub struct RuffSettings {
/// The path to this configuration file, used for debugging. /// The path to this configuration file, used for debugging.
/// The default fallback configuration does not have a file path. /// The default fallback configuration does not have a file path.
path: Option<PathBuf>, path: Option<PathBuf>,
/// Toggle for unsafe fixes. /// The resolved settings.
unsafe_fixes: UnsafeFixes, settings: Settings,
/// Settings used to manage file inclusion and exclusion. }
file_resolver: ruff_workspace::FileResolverSettings,
/// Settings to pass into the Ruff linter. impl Deref for RuffSettings {
linter: ruff_linter::settings::LinterSettings, type Target = Settings;
/// Settings to pass into the Ruff formatter.
formatter: ruff_workspace::FormatterSettings, fn deref(&self) -> &Settings {
&self.settings
}
} }
pub(super) struct RuffSettingsIndex { pub(super) struct RuffSettingsIndex {
@ -42,15 +44,7 @@ pub(super) struct RuffSettingsIndex {
impl std::fmt::Display for RuffSettings { impl std::fmt::Display for RuffSettings {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
display_settings! { std::fmt::Display::fmt(&self.settings, f)
formatter = f,
fields = [
self.file_resolver,
self.linter,
self.formatter
]
}
Ok(())
} }
} }
@ -80,32 +74,9 @@ impl RuffSettings {
RuffSettings { RuffSettings {
path, path,
unsafe_fixes: fallback.unsafe_fixes, settings: fallback,
file_resolver: fallback.file_resolver,
formatter: fallback.formatter,
linter: fallback.linter,
} }
} }
/// Return the [`ruff_workspace::FileResolverSettings`] for this [`RuffSettings`].
pub(crate) fn file_resolver(&self) -> &ruff_workspace::FileResolverSettings {
&self.file_resolver
}
/// Return the [`ruff_linter::settings::LinterSettings`] for this [`RuffSettings`].
pub(crate) fn linter(&self) -> &ruff_linter::settings::LinterSettings {
&self.linter
}
/// Return the [`ruff_workspace::FormatterSettings`] for this [`RuffSettings`].
pub(crate) fn formatter(&self) -> &ruff_workspace::FormatterSettings {
&self.formatter
}
/// Return the [`UnsafeFixes`] for this [`RuffSettings`].
pub(crate) fn unsafe_fixes(&self) -> UnsafeFixes {
self.unsafe_fixes
}
} }
impl RuffSettingsIndex { impl RuffSettingsIndex {
@ -152,10 +123,7 @@ impl RuffSettingsIndex {
directory.to_path_buf(), directory.to_path_buf(),
Arc::new(RuffSettings { Arc::new(RuffSettings {
path: Some(pyproject), path: Some(pyproject),
unsafe_fixes: settings.unsafe_fixes, settings,
file_resolver: settings.file_resolver,
linter: settings.linter,
formatter: settings.formatter,
}), }),
); );
break; break;
@ -210,7 +178,7 @@ impl RuffSettingsIndex {
// Add any settings within the workspace itself // Add any settings within the workspace itself
let mut builder = WalkBuilder::new(root); let mut builder = WalkBuilder::new(root);
builder.standard_filters( builder.standard_filters(
respect_gitignore.unwrap_or_else(|| fallback.file_resolver().respect_gitignore), respect_gitignore.unwrap_or_else(|| fallback.file_resolver.respect_gitignore),
); );
builder.hidden(false); builder.hidden(false);
builder.threads( builder.threads(
@ -277,10 +245,7 @@ impl RuffSettingsIndex {
directory, directory,
Arc::new(RuffSettings { Arc::new(RuffSettings {
path: Some(pyproject), path: Some(pyproject),
unsafe_fixes: settings.unsafe_fixes, settings,
file_resolver: settings.file_resolver,
linter: settings.linter,
formatter: settings.formatter,
}), }),
); );
} }