diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index 8aebb380b6..17233219d7 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -12,7 +12,6 @@ pub struct ProjectSettings { pub git: GitSettings, // TODO kb better names and docs and tests // TODO kb how to react on their changes? - // TODO kb /something/node_modules/ does not match `"**/node_modules/**"` glob!!! #[serde(default)] pub scan_exclude_files: Vec, } diff --git a/crates/project/src/worktree.rs b/crates/project/src/worktree.rs index dbc18e086d..3cc1ff6fef 100644 --- a/crates/project/src/worktree.rs +++ b/crates/project/src/worktree.rs @@ -3598,7 +3598,7 @@ impl BackgroundScanner { for entry in &mut new_entries { state.reuse_entry_id(entry); if entry.is_dir() { - if state.should_scan_directory(&entry, &job.path.join(&entry.path)) { + if state.should_scan_directory(&entry, &root_abs_path.join(&entry.path)) { job_ix += 1; } else { log::debug!("defer scanning directory {:?}", entry.path); diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index d54e0b1cd6..5999bd1d39 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -211,7 +211,19 @@ impl PathMatcher { } pub fn is_match>(&self, other: P) -> bool { - other.as_ref().starts_with(&self.maybe_path) || self.glob.is_match(other) + other.as_ref().starts_with(&self.maybe_path) + || self.glob.is_match(&other) + || self.check_with_end_separator(other.as_ref()) + } + + fn check_with_end_separator(&self, path: &Path) -> bool { + let path_str = path.to_string_lossy(); + let separator = std::path::MAIN_SEPARATOR_STR; + if path_str.ends_with(separator) { + self.glob.is_match(path) + } else { + self.glob.is_match(path_str.to_string() + separator) + } } } @@ -388,4 +400,14 @@ mod tests { let path = Path::new("/a/b/c/.eslintrc.js"); assert_eq!(path.extension_or_hidden_file_name(), Some("js")); } + + #[test] + fn edge_of_glob() { + let path = Path::new("/work/node_modules"); + let path_matcher = PathMatcher::new("**/node_modules/**").unwrap(); + assert!( + path_matcher.is_match(&path), + "Path matcher {path_matcher} should match {path:?}" + ); + } }