From f5c53d1e0e974d37934a0694cacd291853ace728 Mon Sep 17 00:00:00 2001 From: Cameron Date: Mon, 1 Dec 2025 12:29:32 -0500 Subject: [PATCH] Allow for pattern-based memories folder exclusion --- src/memories.rs | 51 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/memories.rs b/src/memories.rs index bf29b9d..c366e10 100644 --- a/src/memories.rs +++ b/src/memories.rs @@ -242,25 +242,52 @@ pub async fn list_memories( let base = Path::new(&app_state.base_path); - // Build a list of excluded directories with full paths - let excluded_paths: Vec = app_state - .excluded_dirs - .iter() - .map(|dir| base.join(dir)) - .collect(); + // Build a list of excluded directories and patterns, all scoped under base: + // - entries starting with '/' are treated as absolute *under base* (e.g. "/foo/bar" -> base/foo/bar) + // - entries without '/' are treated as substring patterns matched anywhere in the path + let mut excluded_dirs: Vec = Vec::new(); + let mut excluded_patterns: Vec = Vec::new(); - debug!("Excluded directories: {:?}", excluded_paths); + for dir in &app_state.excluded_dirs { + if dir.starts_with('/') { + // "Absolute under base": strip leading '/' and join with base + let rel = &dir[1..]; + if !rel.is_empty() { + excluded_dirs.push(base.join(rel)); + } + } else { + // Pure pattern (no '/'): match as substring anywhere in the path + excluded_patterns.push(dir.clone()); + } + } + + debug!("Excluded directories (under base): {:?}", excluded_dirs); + debug!("Excluded path patterns: {:?}", excluded_patterns); let entries: Vec<_> = WalkDir::new(base) .into_iter() .filter_map(|e| e.ok()) .filter(|e| { - // Skip excluded directories - if !excluded_paths.is_empty() { - let path = e.path(); - for excluded in &excluded_paths { + let path = e.path(); + + // Skip excluded directories (all are under base) + if !excluded_dirs.is_empty() { + for excluded in &excluded_dirs { if path.starts_with(excluded) { - debug!("Skipping excluded path: {:?}", path); + debug!("Skipping excluded dir path: {:?}", path); + return false; + } + } + } + + // Skip paths that match any of the relative patterns (substring match under base) + if !excluded_patterns.is_empty() { + if let Some(path_str) = path.to_str() { + if excluded_patterns.iter().any(|pat| path_str.contains(pat)) { + debug!( + "Skipping excluded pattern match: {:?} (patterns: {:?})", + path, excluded_patterns + ); return false; } }