diff --git a/crates/ruff_workspace/src/resolver.rs b/crates/ruff_workspace/src/resolver.rs index aeca97709b0c6..6bf5671a3ca59 100644 --- a/crates/ruff_workspace/src/resolver.rs +++ b/crates/ruff_workspace/src/resolver.rs @@ -9,6 +9,7 @@ use std::sync::RwLock; use anyhow::Result; use anyhow::{anyhow, bail}; +use globset::{Candidate, GlobSet}; use ignore::{WalkBuilder, WalkState}; use itertools::Itertools; use log::debug; @@ -333,12 +334,18 @@ pub fn python_files_in_path( let resolver = resolver.read().unwrap(); let settings = resolver.resolve(path, pyproject_config); if let Some(file_name) = path.file_name() { - if match_exclusion(path, file_name, &settings.file_resolver.exclude) { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return WalkState::Skip; - } else if match_exclusion( - path, - file_name, + } else if match_candidate_exclusion( + &file_path, + &file_basename, &settings.file_resolver.extend_exclude, ) { debug!("Ignored path via `extend-exclude`: {:?}", path); @@ -509,10 +516,20 @@ fn is_file_excluded( for path in path.ancestors() { let settings = resolver.resolve(path, pyproject_strategy); if let Some(file_name) = path.file_name() { - if match_exclusion(path, file_name, &settings.file_resolver.exclude) { + let file_path = Candidate::new(path); + let file_basename = Candidate::new(file_name); + if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.exclude, + ) { debug!("Ignored path via `exclude`: {:?}", path); return true; - } else if match_exclusion(path, file_name, &settings.file_resolver.extend_exclude) { + } else if match_candidate_exclusion( + &file_path, + &file_basename, + &settings.file_resolver.extend_exclude, + ) { debug!("Ignored path via `extend-exclude`: {:?}", path); return true; } @@ -533,11 +550,27 @@ fn is_file_excluded( pub fn match_exclusion, R: AsRef>( file_path: P, file_basename: R, - exclusion: &globset::GlobSet, + exclusion: &GlobSet, ) -> bool { + if exclusion.is_empty() { + return false; + } exclusion.is_match(file_path) || exclusion.is_match(file_basename) } +/// Return `true` if the given candidates should be ignored based on the exclusion +/// criteria. +pub fn match_candidate_exclusion( + file_path: &Candidate, + file_basename: &Candidate, + exclusion: &GlobSet, +) -> bool { + if exclusion.is_empty() { + return false; + } + exclusion.is_match_candidate(file_path) || exclusion.is_match_candidate(file_basename) +} + #[cfg(test)] mod tests { use std::fs::{create_dir, File};