diff --git a/Cargo.lock b/Cargo.lock index cb3c2dc518..86c4a05494 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -727,6 +727,12 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "env_logger" version = "0.10.1" @@ -1321,6 +1327,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.6.4" @@ -1390,6 +1402,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d906846a98739ed9d73d66e62c2641eef8321f1734b7a1156ab045a0248fb2b3" +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + [[package]] name = "nix" version = "0.26.4" @@ -1823,6 +1844,16 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.8.5" @@ -2490,9 +2521,11 @@ dependencies = [ "is-macro", "itertools 0.12.0", "log", + "matchit", "once_cell", "path-absolutize", "pep440_rs 0.4.0", + "radix_trie", "regex", "ruff_cache", "ruff_formatter", diff --git a/crates/ruff_workspace/Cargo.toml b/crates/ruff_workspace/Cargo.toml index b7781678bf..5f704a7e1c 100644 --- a/crates/ruff_workspace/Cargo.toml +++ b/crates/ruff_workspace/Cargo.toml @@ -40,6 +40,8 @@ serde = { workspace = true} shellexpand = { workspace = true } strum = { workspace = true } toml = { workspace = true } +matchit = "0.7.3" +radix_trie = "0.2.1" [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index ac1f94294a..8ea7ab8c32 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -2,7 +2,6 @@ //! filesystem. use std::cmp::Ordering; -use std::collections::BTreeMap; use std::ffi::OsStr; use std::path::{Path, PathBuf}; use std::sync::RwLock; @@ -13,6 +12,7 @@ use globset::{Candidate, GlobSet}; use ignore::{WalkBuilder, WalkState}; use itertools::Itertools; use log::debug; +use matchit::Router; use path_absolutize::path_dedot; use rustc_hash::{FxHashMap, FxHashSet}; @@ -96,13 +96,15 @@ impl Relativity { #[derive(Default)] pub struct Resolver { - settings: BTreeMap, + router: Router, } impl Resolver { /// Add a resolved [`Settings`] under a given [`PathBuf`] scope. - fn add(&mut self, path: PathBuf, settings: Settings) { - self.settings.insert(path, settings); + fn add(&mut self, path: PathBuf, settings: Settings) -> Result<()> { + Ok(self + .router + .insert(format!("{}/*filepath", path.display()), settings)?) } /// Return the appropriate [`Settings`] for a given [`Path`]. @@ -114,11 +116,9 @@ impl Resolver { match pyproject_config.strategy { PyprojectDiscoveryStrategy::Fixed => &pyproject_config.settings, PyprojectDiscoveryStrategy::Hierarchical => self - .settings - .iter() - .rev() - .find_map(|(root, settings)| path.starts_with(root).then_some(settings)) - .unwrap_or(&pyproject_config.settings), + .router + .at(path.to_string_lossy().as_ref()) + .map_or_else(|_| &pyproject_config.settings, |match_| match_.value), } } @@ -162,7 +162,7 @@ impl Resolver { /// Return an iterator over the resolved [`Settings`] in this [`Resolver`]. pub fn settings(&self) -> impl Iterator { - self.settings.values() + std::iter::empty() } }