From 451047c30ddcac143f3d5f9958e0c8bcd5744a9c Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Thu, 22 Dec 2022 15:07:22 -0500 Subject: [PATCH] Exclude directly-passed files nested in excluded subdirectories --- src/resolver.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/resolver.rs b/src/resolver.rs index a9eb336b2ac61..95ad0f609281d 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -190,7 +190,7 @@ pub fn python_files_in_path( overrides: &Overrides, ) -> Result<(Vec>, Resolver)> { // Normalize every path (e.g., convert from relative to absolute). - let paths: Vec = paths.iter().map(fs::normalize_path).collect(); + let mut paths: Vec = paths.iter().map(fs::normalize_path).collect(); // Search for `pyproject.toml` files in all parent directories. let mut resolver = Resolver::default(); @@ -207,6 +207,40 @@ pub fn python_files_in_path( } } + // Omit any paths that are nested within excluded ancestors. This ensures that + // if we pass `subdir/file.py`, and `subdir` is excluded, then we don't + // "miss" that exclusion when walking from `subdir/file.py` below. + if file_strategy.force_exclude { + paths.retain(|path| { + for path in path.ancestors() { + let settings = resolver.resolve(path, pyproject_strategy); + match fs::extract_path_names(path) { + Ok((file_path, file_basename)) => { + if !settings.exclude.is_empty() + && is_excluded(file_path, file_basename, &settings.exclude) + { + debug!("Ignored path via `exclude`: {:?}", path); + return false; + } else if !settings.extend_exclude.is_empty() + && is_excluded(file_path, file_basename, &settings.extend_exclude) + { + debug!("Ignored path via `extend-exclude`: {:?}", path); + return false; + } + } + Err(err) => { + debug!("Ignored path due to error in parsing: {:?}: {}", path, err); + return false; + } + } + } + true + }); + if paths.is_empty() { + return Ok((vec![], resolver)); + } + } + // Create the `WalkBuilder`. let mut builder = WalkBuilder::new( paths