mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 05:25:17 +00:00
Build settings index in parallel for the native server (#12299)
## Summary This PR updates the server to build the settings index in parallel using similar logic as `python_files_in_path`. This should help with https://github.com/astral-sh/ruff/issues/11366 but ideally we would want to build it lazily. ## Test Plan `cargo insta test`
This commit is contained in:
parent
b9a8cd390f
commit
ecd4b4d943
3 changed files with 82 additions and 62 deletions
|
@ -1,3 +1,9 @@
|
|||
use std::collections::BTreeMap;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use ignore::{WalkBuilder, WalkState};
|
||||
|
||||
use ruff_linter::{
|
||||
display_settings, fs::normalize_path_to, settings::types::FilePattern,
|
||||
settings::types::PreviewMode,
|
||||
|
@ -8,12 +14,6 @@ use ruff_workspace::{
|
|||
pyproject::{find_user_settings_toml, settings_toml},
|
||||
resolver::{ConfigurationTransformer, Relativity},
|
||||
};
|
||||
use std::{
|
||||
collections::BTreeMap,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::session::settings::{ConfigurationPreference, ResolvedEditorSettings};
|
||||
|
||||
|
@ -30,7 +30,7 @@ pub struct RuffSettings {
|
|||
}
|
||||
|
||||
pub(super) struct RuffSettingsIndex {
|
||||
/// Index from folder to the resoled ruff settings.
|
||||
/// Index from folder to the resolved ruff settings.
|
||||
index: BTreeMap<PathBuf, Arc<RuffSettings>>,
|
||||
fallback: Arc<RuffSettings>,
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ impl RuffSettings {
|
|||
impl RuffSettingsIndex {
|
||||
pub(super) fn new(root: &Path, editor_settings: &ResolvedEditorSettings) -> Self {
|
||||
let mut index = BTreeMap::default();
|
||||
let mut respect_gitignore = true;
|
||||
|
||||
// Add any settings from above the workspace root.
|
||||
for directory in root.ancestors() {
|
||||
|
@ -112,6 +113,7 @@ impl RuffSettingsIndex {
|
|||
continue;
|
||||
};
|
||||
|
||||
respect_gitignore = settings.file_resolver.respect_gitignore;
|
||||
index.insert(
|
||||
directory.to_path_buf(),
|
||||
Arc::new(RuffSettings {
|
||||
|
@ -126,70 +128,88 @@ impl RuffSettingsIndex {
|
|||
}
|
||||
|
||||
// Add any settings within the workspace itself
|
||||
let mut walker = WalkDir::new(root).into_iter();
|
||||
let mut builder = WalkBuilder::new(root);
|
||||
builder.standard_filters(respect_gitignore);
|
||||
builder.hidden(false);
|
||||
builder.threads(
|
||||
std::thread::available_parallelism()
|
||||
.map_or(1, std::num::NonZeroUsize::get)
|
||||
.min(12),
|
||||
);
|
||||
let walker = builder.build_parallel();
|
||||
|
||||
while let Some(entry) = walker.next() {
|
||||
let Ok(entry) = entry else {
|
||||
continue;
|
||||
};
|
||||
let index = std::sync::RwLock::new(index);
|
||||
walker.run(|| {
|
||||
Box::new(|result| {
|
||||
let Ok(entry) = result else {
|
||||
return WalkState::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))
|
||||
// Skip non-directories.
|
||||
if !entry
|
||||
.file_type()
|
||||
.is_some_and(|file_type| file_type.is_dir())
|
||||
{
|
||||
if match_exclusion(&directory, file_name, &settings.file_resolver.exclude) {
|
||||
tracing::debug!("Ignored path via `exclude`: {}", directory.display());
|
||||
return WalkState::Continue;
|
||||
}
|
||||
|
||||
walker.skip_current_dir();
|
||||
continue;
|
||||
} else if match_exclusion(
|
||||
&directory,
|
||||
file_name,
|
||||
&settings.file_resolver.extend_exclude,
|
||||
) {
|
||||
tracing::debug!(
|
||||
"Ignored path via `extend-exclude`: {}",
|
||||
directory.display()
|
||||
);
|
||||
let directory = entry.into_path();
|
||||
tracing::debug!("Visiting: {}", directory.display());
|
||||
|
||||
walker.skip_current_dir();
|
||||
continue;
|
||||
// If the directory is excluded from the workspace, skip it.
|
||||
if let Some(file_name) = directory.file_name() {
|
||||
if let Some((_, settings)) = index
|
||||
.read()
|
||||
.unwrap()
|
||||
.range(..directory.clone())
|
||||
.rfind(|(path, _)| directory.starts_with(path))
|
||||
{
|
||||
if match_exclusion(&directory, file_name, &settings.file_resolver.exclude) {
|
||||
tracing::debug!("Ignored path via `exclude`: {}", directory.display());
|
||||
return WalkState::Continue;
|
||||
} else if match_exclusion(
|
||||
&directory,
|
||||
file_name,
|
||||
&settings.file_resolver.extend_exclude,
|
||||
) {
|
||||
tracing::debug!(
|
||||
"Ignored path via `extend-exclude`: {}",
|
||||
directory.display()
|
||||
);
|
||||
return WalkState::Continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
|
||||
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
||||
&pyproject,
|
||||
Relativity::Parent,
|
||||
&EditorConfigurationTransformer(editor_settings, root),
|
||||
) else {
|
||||
continue;
|
||||
};
|
||||
index.insert(
|
||||
directory,
|
||||
Arc::new(RuffSettings {
|
||||
path: Some(pyproject),
|
||||
file_resolver: settings.file_resolver,
|
||||
linter: settings.linter,
|
||||
formatter: settings.formatter,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(pyproject) = settings_toml(&directory).ok().flatten() {
|
||||
let Ok(settings) = ruff_workspace::resolver::resolve_root_settings(
|
||||
&pyproject,
|
||||
Relativity::Parent,
|
||||
&EditorConfigurationTransformer(editor_settings, root),
|
||||
) else {
|
||||
return WalkState::Continue;
|
||||
};
|
||||
index.write().unwrap().insert(
|
||||
directory,
|
||||
Arc::new(RuffSettings {
|
||||
path: Some(pyproject),
|
||||
file_resolver: settings.file_resolver,
|
||||
linter: settings.linter,
|
||||
formatter: settings.formatter,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
WalkState::Continue
|
||||
})
|
||||
});
|
||||
|
||||
let fallback = Arc::new(RuffSettings::fallback(editor_settings, root));
|
||||
|
||||
Self { index, fallback }
|
||||
Self {
|
||||
index: index.into_inner().unwrap(),
|
||||
fallback,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn get(&self, document_path: &Path) -> Arc<RuffSettings> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue