Exclude globsets for --show-settings (#3201)

This commit is contained in:
Charlie Marsh 2023-02-23 23:23:00 -05:00 committed by GitHub
parent da98fab4ae
commit eef85067c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 16 deletions

12
Cargo.lock generated
View File

@ -598,6 +598,17 @@ dependencies = [
"syn", "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]] [[package]]
name = "diff" name = "diff"
version = "0.1.13" version = "0.1.13"
@ -1982,6 +1993,7 @@ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"console_log", "console_log",
"criterion", "criterion",
"derivative",
"dirs", "dirs",
"fern", "fern",
"getrandom", "getrandom",

View File

@ -27,6 +27,7 @@ cfg-if = { version = "1.0.0" }
chrono = { version = "0.4.21", default-features = false, features = ["clock"] } chrono = { version = "0.4.21", default-features = false, features = ["clock"] }
clap = { workspace = true, features = ["derive", "env", "string"] } clap = { workspace = true, features = ["derive", "env", "string"] }
colored = { version = "2.0.0" } colored = { version = "2.0.0" }
derivative = { version = "2.2.0" }
dirs = { version = "4.0.0" } dirs = { version = "4.0.0" }
fern = { version = "0.6.1" } fern = { version = "0.6.1" }
glob = { version = "0.3.0" } glob = { version = "0.3.0" }

View File

@ -1,4 +1,4 @@
//! Discover Python files, and their corresponding `Settings`, from the //! Discover Python files, and their corresponding [`Settings`], from the
//! filesystem. //! filesystem.
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -65,12 +65,12 @@ pub struct Resolver {
} }
impl 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) { pub fn add(&mut self, path: PathBuf, settings: AllSettings) {
self.settings.insert(path, settings); 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>( pub fn resolve_all<'a>(
&'a self, &'a self,
path: &Path, path: &Path,
@ -91,7 +91,7 @@ impl Resolver {
&self.resolve_all(path, strategy).lib &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<Item = &AllSettings> { pub fn iter(&self) -> impl Iterator<Item = &AllSettings> {
self.settings.values() self.settings.values()
} }
@ -106,8 +106,8 @@ impl ConfigProcessor for &NoOpProcessor {
fn process_config(&self, _config: &mut Configuration) {} fn process_config(&self, _config: &mut Configuration) {}
} }
/// Recursively resolve a `Configuration` from a `pyproject.toml` file at the /// Recursively resolve a [`Configuration`] from a `pyproject.toml` file at the
/// specified `Path`. /// specified [`Path`].
// TODO(charlie): This whole system could do with some caching. Right now, if a // 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 // 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 // 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) Ok(configuration)
} }
/// Extract the project root (scope) and `Settings` from a given /// Extract the project root (scope) and [`Settings`] from a given
/// `pyproject.toml`. /// `pyproject.toml`.
pub fn resolve_scoped_settings( pub fn resolve_scoped_settings(
pyproject: &Path, pyproject: &Path,
relativity: &Relativity, relativity: &Relativity,
processor: impl ConfigProcessor, processor: impl ConfigProcessor,
) -> Result<(PathBuf, AllSettings)> { ) -> Result<(PathBuf, AllSettings)> {
let project_root = relativity.resolve(pyproject);
let configuration = resolve_configuration(pyproject, relativity, processor)?; let configuration = resolve_configuration(pyproject, relativity, processor)?;
let project_root = relativity.resolve(pyproject);
let settings = AllSettings::from_configuration(configuration, &project_root)?; let settings = AllSettings::from_configuration(configuration, &project_root)?;
Ok((project_root, settings)) 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<AllSettings> { pub fn resolve_settings(pyproject: &Path, relativity: &Relativity) -> Result<AllSettings> {
let (_project_root, settings) = resolve_scoped_settings(pyproject, relativity, &NoOpProcessor)?; let (_project_root, settings) = resolve_scoped_settings(pyproject, relativity, &NoOpProcessor)?;
Ok(settings) 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`]. /// configuration with the given [`ConfigProcessor`].
pub fn resolve_settings_with_processor( pub fn resolve_settings_with_processor(
pyproject: &Path, 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) 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 { fn is_python_path(path: &Path) -> bool {
path.extension() path.extension()
.map_or(false, |ext| ext == "py" || ext == "pyi") .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 { pub fn is_interface_definition_path(path: &Path) -> bool {
path.extension().map_or(false, |ext| ext == "pyi") 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 { pub fn is_python_entry(entry: &DirEntry) -> bool {
is_python_path(entry.path()) is_python_path(entry.path())
&& !entry && !entry
@ -351,7 +351,7 @@ pub fn python_files_in_path(
Ok((files.into_inner().unwrap(), resolver.into_inner().unwrap())) 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( pub fn python_file_at_path(
path: &Path, path: &Path,
pyproject_strategy: &PyprojectDiscovery, pyproject_strategy: &PyprojectDiscovery,
@ -380,7 +380,7 @@ pub fn python_file_at_path(
Ok(!is_file_excluded(&path, &resolver, pyproject_strategy)) 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( fn is_file_excluded(
path: &Path, path: &Path,
resolver: &Resolver, resolver: &Resolver,

View File

@ -1,3 +1,4 @@
use derivative::Derivative;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@ -54,9 +55,11 @@ impl Hash for HashableGlobMatcher {
} }
} }
#[derive(Debug)] #[derive(Derivative)]
#[derivative(Debug)]
pub struct HashableGlobSet { pub struct HashableGlobSet {
patterns: Vec<FilePattern>, patterns: Vec<FilePattern>,
#[derivative(Debug = "ignore")]
globset: GlobSet, globset: GlobSet,
} }