diff --git a/Cargo.lock b/Cargo.lock index 668a7613b3..a5c93dfe18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -598,6 +598,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "diff" version = "0.1.13" @@ -1982,6 +1993,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "criterion", + "derivative", "dirs", "fern", "getrandom", diff --git a/crates/ruff/Cargo.toml b/crates/ruff/Cargo.toml index f83a04b658..8131efeaa3 100644 --- a/crates/ruff/Cargo.toml +++ b/crates/ruff/Cargo.toml @@ -27,6 +27,7 @@ cfg-if = { version = "1.0.0" } chrono = { version = "0.4.21", default-features = false, features = ["clock"] } clap = { workspace = true, features = ["derive", "env", "string"] } colored = { version = "2.0.0" } +derivative = { version = "2.2.0" } dirs = { version = "4.0.0" } fern = { version = "0.6.1" } glob = { version = "0.3.0" } diff --git a/crates/ruff/src/resolver.rs b/crates/ruff/src/resolver.rs index 59154920a4..9206e36c51 100644 --- a/crates/ruff/src/resolver.rs +++ b/crates/ruff/src/resolver.rs @@ -1,4 +1,4 @@ -//! Discover Python files, and their corresponding `Settings`, from the +//! Discover Python files, and their corresponding [`Settings`], from the //! filesystem. use std::collections::BTreeMap; @@ -65,12 +65,12 @@ pub struct Resolver { } impl Resolver { - /// Add a resolved `Settings` under a given `PathBuf` scope. + /// Add a resolved [`Settings`] under a given [`PathBuf`] scope. pub fn add(&mut self, path: PathBuf, settings: AllSettings) { self.settings.insert(path, settings); } - /// Return the appropriate `AllSettings` for a given `Path`. + /// Return the appropriate [`AllSettings`] for a given [`Path`]. pub fn resolve_all<'a>( &'a self, path: &Path, @@ -91,7 +91,7 @@ impl Resolver { &self.resolve_all(path, strategy).lib } - /// Return an iterator over the resolved `Settings` in this `Resolver`. + /// Return an iterator over the resolved [`Settings`] in this [`Resolver`]. pub fn iter(&self) -> impl Iterator { self.settings.values() } @@ -106,8 +106,8 @@ impl ConfigProcessor for &NoOpProcessor { fn process_config(&self, _config: &mut Configuration) {} } -/// Recursively resolve a `Configuration` from a `pyproject.toml` file at the -/// specified `Path`. +/// Recursively resolve a [`Configuration`] from a `pyproject.toml` file at the +/// specified [`Path`]. // TODO(charlie): This whole system could do with some caching. Right now, if a // configuration file extends another in the same path, we'll re-parse the same // file at least twice (possibly more than twice, since we'll also parse it when @@ -155,26 +155,26 @@ pub fn resolve_configuration( Ok(configuration) } -/// Extract the project root (scope) and `Settings` from a given +/// Extract the project root (scope) and [`Settings`] from a given /// `pyproject.toml`. pub fn resolve_scoped_settings( pyproject: &Path, relativity: &Relativity, processor: impl ConfigProcessor, ) -> Result<(PathBuf, AllSettings)> { - let project_root = relativity.resolve(pyproject); let configuration = resolve_configuration(pyproject, relativity, processor)?; + let project_root = relativity.resolve(pyproject); let settings = AllSettings::from_configuration(configuration, &project_root)?; Ok((project_root, settings)) } -/// Extract the `Settings` from a given `pyproject.toml`. +/// Extract the [`Settings`] from a given `pyproject.toml`. pub fn resolve_settings(pyproject: &Path, relativity: &Relativity) -> Result { let (_project_root, settings) = resolve_scoped_settings(pyproject, relativity, &NoOpProcessor)?; Ok(settings) } -/// Extract the `Settings` from a given `pyproject.toml` and process the +/// Extract the [`Settings`] from a given `pyproject.toml` and process the /// configuration with the given [`ConfigProcessor`]. pub fn resolve_settings_with_processor( pyproject: &Path, @@ -191,18 +191,18 @@ fn match_exclusion(file_path: &str, file_basename: &str, exclusion: &globset::Gl exclusion.is_match(file_path) || exclusion.is_match(file_basename) } -/// Return `true` if the `Path` appears to be that of a Python file. +/// Return `true` if the [`Path`] appears to be that of a Python file. fn is_python_path(path: &Path) -> bool { path.extension() .map_or(false, |ext| ext == "py" || ext == "pyi") } -/// Return `true` if the `Path` appears to be that of a Python interface definition file (`.pyi`). +/// Return `true` if the [`Path`] appears to be that of a Python interface definition file (`.pyi`). pub fn is_interface_definition_path(path: &Path) -> bool { path.extension().map_or(false, |ext| ext == "pyi") } -/// Return `true` if the `Entry` appears to be that of a Python file. +/// Return `true` if the [`DirEntry`] appears to be that of a Python file. pub fn is_python_entry(entry: &DirEntry) -> bool { is_python_path(entry.path()) && !entry @@ -351,7 +351,7 @@ pub fn python_files_in_path( Ok((files.into_inner().unwrap(), resolver.into_inner().unwrap())) } -/// Return `true` if the Python file at `Path` is _not_ excluded. +/// Return `true` if the Python file at [`Path`] is _not_ excluded. pub fn python_file_at_path( path: &Path, pyproject_strategy: &PyprojectDiscovery, @@ -380,7 +380,7 @@ pub fn python_file_at_path( Ok(!is_file_excluded(&path, &resolver, pyproject_strategy)) } -/// Return `true` if the given top-level `Path` should be excluded. +/// Return `true` if the given top-level [`Path`] should be excluded. fn is_file_excluded( path: &Path, resolver: &Resolver, diff --git a/crates/ruff/src/settings/hashable.rs b/crates/ruff/src/settings/hashable.rs index b7c8b98e28..504ca9bb7e 100644 --- a/crates/ruff/src/settings/hashable.rs +++ b/crates/ruff/src/settings/hashable.rs @@ -1,3 +1,4 @@ +use derivative::Derivative; use std::hash::{Hash, Hasher}; use std::ops::{Deref, DerefMut}; @@ -54,9 +55,11 @@ impl Hash for HashableGlobMatcher { } } -#[derive(Debug)] +#[derive(Derivative)] +#[derivative(Debug)] pub struct HashableGlobSet { patterns: Vec, + #[derivative(Debug = "ignore")] globset: GlobSet, }