Skip to content

Commit 16a1f3c

Browse files
authored
ruff server: Support setting to prioritize project configuration over editor configuration (#11086)
## Summary This is intended to address astral-sh/ruff-vscode#425, and is a follow-up to #11062. A new client setting is now supported by the server, `prioritizeFileConfiguration`. This is a boolean setting (default: `false`) that, if set to `true`, will instruct the configuration resolver to prioritize file configuration (aka discovered TOML files) over configuration passed in by the editor. A corresponding extension PR has been opened, which makes this setting available for VS Code: astral-sh/ruff-vscode#457. ## Test Plan To test this with VS Code, you'll need to check out [the VS Code PR](astral-sh/ruff-vscode#457) that adds this setting. The test process is similar to #11062, but in scenarios where the editor configuration would take priority over file configuration, file configuration should take priority.
1 parent cd3e319 commit 16a1f3c

2 files changed

Lines changed: 46 additions & 7 deletions

File tree

crates/ruff_server/src/session/settings.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub(crate) struct ResolvedClientSettings {
2828
/// Contains the resolved values of 'editor settings' - Ruff configuration for the linter/formatter that was passed in via
2929
/// LSP client settings. These fields are optional because we don't want to override file-based linter/formatting settings
3030
/// if these were un-set.
31-
#[derive(Clone, Debug, Default)]
31+
#[derive(Clone, Debug)]
3232
#[cfg_attr(test, derive(PartialEq, Eq))]
3333
pub(crate) struct ResolvedEditorSettings {
3434
pub(super) lint_preview: Option<bool>,
@@ -38,6 +38,23 @@ pub(crate) struct ResolvedEditorSettings {
3838
pub(super) ignore: Option<Vec<RuleSelector>>,
3939
pub(super) exclude: Option<Vec<String>>,
4040
pub(super) line_length: Option<LineLength>,
41+
pub(super) configuration_preference: ConfigurationPreference,
42+
}
43+
44+
/// Determines how multiple conflicting configurations should be resolved - in this
45+
/// case, the configuration from the client settings and configuration from local
46+
/// `.toml` files (aka 'workspace' configuration).
47+
#[derive(Clone, Copy, Debug, Deserialize, Default)]
48+
#[cfg_attr(test, derive(PartialEq, Eq))]
49+
#[serde(rename_all = "camelCase")]
50+
pub(crate) enum ConfigurationPreference {
51+
/// Configuration set in the editor takes priority over workspace configuration set in `.toml` files.
52+
#[default]
53+
EditorFirst,
54+
/// Configuration set in `.toml` files takes priority over configuration set in the editor.
55+
FilesystemFirst,
56+
/// `.toml` files are ignored completely, and only the editor configuration is used.
57+
EditorOnly,
4158
}
4259

4360
/// This is a direct representation of the settings schema sent by the client.
@@ -52,6 +69,7 @@ pub(crate) struct ClientSettings {
5269
code_action: Option<CodeActionOptions>,
5370
exclude: Option<Vec<String>>,
5471
line_length: Option<LineLength>,
72+
configuration_preference: Option<ConfigurationPreference>,
5573
}
5674

5775
/// This is a direct representation of the workspace settings schema,
@@ -251,6 +269,11 @@ impl ResolvedClientSettings {
251269
Some(settings.exclude.as_ref()?.clone())
252270
}),
253271
line_length: Self::resolve_optional(all_settings, |settings| settings.line_length),
272+
configuration_preference: Self::resolve_or(
273+
all_settings,
274+
|settings| settings.configuration_preference,
275+
ConfigurationPreference::EditorFirst,
276+
),
254277
},
255278
}
256279
}
@@ -383,6 +406,7 @@ mod tests {
383406
),
384407
exclude: None,
385408
line_length: None,
409+
configuration_preference: None,
386410
},
387411
workspace_settings: [
388412
WorkspaceSettings {
@@ -429,6 +453,7 @@ mod tests {
429453
),
430454
exclude: None,
431455
line_length: None,
456+
configuration_preference: None,
432457
},
433458
workspace: Url {
434459
scheme: "file",
@@ -488,6 +513,7 @@ mod tests {
488513
),
489514
exclude: None,
490515
line_length: None,
516+
configuration_preference: None,
491517
},
492518
workspace: Url {
493519
scheme: "file",
@@ -538,7 +564,8 @@ mod tests {
538564
extend_select: None,
539565
ignore: None,
540566
exclude: None,
541-
line_length: None
567+
line_length: None,
568+
configuration_preference: ConfigurationPreference::default(),
542569
}
543570
}
544571
);
@@ -566,7 +593,8 @@ mod tests {
566593
extend_select: None,
567594
ignore: None,
568595
exclude: None,
569-
line_length: None
596+
line_length: None,
597+
configuration_preference: ConfigurationPreference::EditorFirst,
570598
}
571599
}
572600
);
@@ -620,6 +648,7 @@ mod tests {
620648
80,
621649
),
622650
),
651+
configuration_preference: None,
623652
},
624653
),
625654
}
@@ -648,7 +677,8 @@ mod tests {
648677
extend_select: None,
649678
ignore: Some(vec![RuleSelector::from_str("RUF001").unwrap()]),
650679
exclude: Some(vec!["third_party".into()]),
651-
line_length: Some(LineLength::try_from(80).unwrap())
680+
line_length: Some(LineLength::try_from(80).unwrap()),
681+
configuration_preference: ConfigurationPreference::EditorFirst,
652682
}
653683
}
654684
);

crates/ruff_server/src/session/workspace/ruff_settings.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{
1414
};
1515
use walkdir::{DirEntry, WalkDir};
1616

17-
use crate::session::settings::ResolvedEditorSettings;
17+
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
1818

1919
#[derive(Default)]
2020
pub(crate) struct RuffSettings {
@@ -107,7 +107,7 @@ struct EditorConfigurationTransformer<'a>(&'a ResolvedEditorSettings, &'a Path);
107107
impl<'a> ConfigurationTransformer for EditorConfigurationTransformer<'a> {
108108
fn transform(
109109
&self,
110-
project_configuration: ruff_workspace::configuration::Configuration,
110+
filesystem_configuration: ruff_workspace::configuration::Configuration,
111111
) -> ruff_workspace::configuration::Configuration {
112112
let ResolvedEditorSettings {
113113
format_preview,
@@ -117,6 +117,7 @@ impl<'a> ConfigurationTransformer for EditorConfigurationTransformer<'a> {
117117
ignore,
118118
exclude,
119119
line_length,
120+
configuration_preference,
120121
} = self.0.clone();
121122

122123
let project_root = self.1;
@@ -149,6 +150,14 @@ impl<'a> ConfigurationTransformer for EditorConfigurationTransformer<'a> {
149150
..Default::default()
150151
};
151152

152-
editor_configuration.combine(project_configuration)
153+
match configuration_preference {
154+
ConfigurationPreference::EditorFirst => {
155+
editor_configuration.combine(filesystem_configuration)
156+
}
157+
ConfigurationPreference::FilesystemFirst => {
158+
filesystem_configuration.combine(editor_configuration)
159+
}
160+
ConfigurationPreference::EditorOnly => editor_configuration,
161+
}
153162
}
154163
}

0 commit comments

Comments
 (0)