mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 12:55:05 +00:00
Respect excludes in ruff server
configuration discovery (#11551)
## Summary
Right now, we're discovering configuration files even within (e.g.)
virtual environments, because we're recursing without respecting the
`exclude` field on parent configuration.
Closes https://github.com/astral-sh/ruff-vscode/issues/478.
## Test Plan
Installed Pandas; verified that I saw no warnings:

This commit is contained in:
parent
adc0a5d126
commit
34a5063aa2
3 changed files with 61 additions and 20 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2367,6 +2367,7 @@ version = "0.2.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
|
"globset",
|
||||||
"insta",
|
"insta",
|
||||||
"jod-thread",
|
"jod-thread",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
@ -28,6 +28,7 @@ ruff_workspace = { workspace = true }
|
||||||
|
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
crossbeam = { workspace = true }
|
crossbeam = { workspace = true }
|
||||||
|
globset = { workspace = true }
|
||||||
jod-thread = { workspace = true }
|
jod-thread = { workspace = true }
|
||||||
lsp-server = { workspace = true }
|
lsp-server = { workspace = true }
|
||||||
lsp-types = { workspace = true }
|
lsp-types = { workspace = true }
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
use globset::Candidate;
|
||||||
use ruff_linter::{
|
use ruff_linter::{
|
||||||
display_settings, fs::normalize_path_to, settings::types::FilePattern,
|
display_settings, fs::normalize_path_to, settings::types::FilePattern,
|
||||||
settings::types::PreviewMode,
|
settings::types::PreviewMode,
|
||||||
};
|
};
|
||||||
|
use ruff_workspace::resolver::match_candidate_exclusion;
|
||||||
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},
|
||||||
|
@ -12,12 +14,13 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use walkdir::{DirEntry, WalkDir};
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
|
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub(crate) struct RuffSettings {
|
pub(crate) struct RuffSettings {
|
||||||
|
/// Settings used to manage file inclusion and exclusion.
|
||||||
|
file_resolver: ruff_workspace::FileResolverSettings,
|
||||||
/// Settings to pass into the Ruff linter.
|
/// Settings to pass into the Ruff linter.
|
||||||
linter: ruff_linter::settings::LinterSettings,
|
linter: ruff_linter::settings::LinterSettings,
|
||||||
/// Settings to pass into the Ruff formatter.
|
/// Settings to pass into the Ruff formatter.
|
||||||
|
@ -54,7 +57,7 @@ impl RuffSettings {
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
let default_configuration = ruff_workspace::configuration::Configuration::default();
|
let default_configuration = Configuration::default();
|
||||||
EditorConfigurationTransformer(editor_settings, root)
|
EditorConfigurationTransformer(editor_settings, root)
|
||||||
.transform(default_configuration)
|
.transform(default_configuration)
|
||||||
.into_settings(root)
|
.into_settings(root)
|
||||||
|
@ -64,6 +67,7 @@ impl RuffSettings {
|
||||||
});
|
});
|
||||||
|
|
||||||
RuffSettings {
|
RuffSettings {
|
||||||
|
file_resolver: fallback.file_resolver,
|
||||||
formatter: fallback.formatter,
|
formatter: fallback.formatter,
|
||||||
linter: fallback.linter,
|
linter: fallback.linter,
|
||||||
}
|
}
|
||||||
|
@ -85,10 +89,6 @@ impl RuffSettingsIndex {
|
||||||
// Add any settings from above the workspace root.
|
// Add any settings from above the workspace root.
|
||||||
for directory in root.ancestors() {
|
for directory in root.ancestors() {
|
||||||
if let Some(pyproject) = settings_toml(directory).ok().flatten() {
|
if let Some(pyproject) = settings_toml(directory).ok().flatten() {
|
||||||
if index.contains_key(&pyproject) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
||||||
&pyproject,
|
&pyproject,
|
||||||
Relativity::Parent,
|
Relativity::Parent,
|
||||||
|
@ -96,9 +96,11 @@ impl RuffSettingsIndex {
|
||||||
) else {
|
) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
index.insert(
|
index.insert(
|
||||||
directory.to_path_buf(),
|
directory.to_path_buf(),
|
||||||
Arc::new(RuffSettings {
|
Arc::new(RuffSettings {
|
||||||
|
file_resolver: settings.file_resolver,
|
||||||
linter: settings.linter,
|
linter: settings.linter,
|
||||||
formatter: settings.formatter,
|
formatter: settings.formatter,
|
||||||
}),
|
}),
|
||||||
|
@ -107,18 +109,55 @@ impl RuffSettingsIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add any settings within the workspace itself.
|
// Add any settings within the workspace itself
|
||||||
for directory in WalkDir::new(root)
|
let mut walker = WalkDir::new(root).into_iter();
|
||||||
.into_iter()
|
|
||||||
.filter_map(Result::ok)
|
|
||||||
.filter(|entry| entry.file_type().is_dir())
|
|
||||||
.map(DirEntry::into_path)
|
|
||||||
{
|
|
||||||
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
|
|
||||||
if index.contains_key(&pyproject) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
while let Some(entry) = walker.next() {
|
||||||
|
let Ok(entry) = entry else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Skip non-directories.
|
||||||
|
if !entry.file_type().is_dir() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let directory = entry.into_path();
|
||||||
|
|
||||||
|
// If the directory is excluded from the workspace, skip it.
|
||||||
|
if let Some(file_name) = directory.file_name() {
|
||||||
|
if let Some((_, settings)) = index
|
||||||
|
.range(..directory.clone())
|
||||||
|
.rfind(|(path, _)| directory.starts_with(path))
|
||||||
|
{
|
||||||
|
let candidate = Candidate::new(&directory);
|
||||||
|
let basename = Candidate::new(file_name);
|
||||||
|
if match_candidate_exclusion(
|
||||||
|
&candidate,
|
||||||
|
&basename,
|
||||||
|
&settings.file_resolver.exclude,
|
||||||
|
) {
|
||||||
|
tracing::debug!("Ignored path via `exclude`: {}", directory.display());
|
||||||
|
|
||||||
|
walker.skip_current_dir();
|
||||||
|
continue;
|
||||||
|
} else if match_candidate_exclusion(
|
||||||
|
&candidate,
|
||||||
|
&basename,
|
||||||
|
&settings.file_resolver.extend_exclude,
|
||||||
|
) {
|
||||||
|
tracing::debug!(
|
||||||
|
"Ignored path via `extend-exclude`: {}",
|
||||||
|
directory.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
walker.skip_current_dir();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
|
||||||
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
||||||
&pyproject,
|
&pyproject,
|
||||||
Relativity::Parent,
|
Relativity::Parent,
|
||||||
|
@ -129,6 +168,7 @@ impl RuffSettingsIndex {
|
||||||
index.insert(
|
index.insert(
|
||||||
directory,
|
directory,
|
||||||
Arc::new(RuffSettings {
|
Arc::new(RuffSettings {
|
||||||
|
file_resolver: settings.file_resolver,
|
||||||
linter: settings.linter,
|
linter: settings.linter,
|
||||||
formatter: settings.formatter,
|
formatter: settings.formatter,
|
||||||
}),
|
}),
|
||||||
|
@ -145,8 +185,7 @@ impl RuffSettingsIndex {
|
||||||
if let Some((_, settings)) = self
|
if let Some((_, settings)) = self
|
||||||
.index
|
.index
|
||||||
.range(..document_path.to_path_buf())
|
.range(..document_path.to_path_buf())
|
||||||
.rev()
|
.rfind(|(path, _)| document_path.starts_with(path))
|
||||||
.find(|(path, _)| document_path.starts_with(path))
|
|
||||||
{
|
{
|
||||||
return settings.clone();
|
return settings.clone();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue