use anyhow::Result;
use std::fs;
use std::path::{Path, PathBuf};
pub fn find_files(dir: &Path, pattern: &str) -> Result<Vec<PathBuf>> {
let mut files = Vec::new();
find_files_recursive(dir, pattern, &mut files)?;
Ok(files)
}
fn find_files_recursive(dir: &Path, pattern: &str, files: &mut Vec<PathBuf>) -> Result<()> {
if !dir.is_dir() {
return Ok(());
}
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
find_files_recursive(&path, pattern, files)?;
} else if path.is_file()
&& let Some(name) = path.file_name()
&& name.to_string_lossy().contains(pattern)
{
files.push(path);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[test]
fn test_find_files() {
let temp = tempdir().unwrap();
let root = temp.path();
std::fs::write(root.join("test.rs"), "").unwrap();
std::fs::write(root.join("main.rs"), "").unwrap();
crate::utils::fs::ensure_dir(&root.join("src")).unwrap();
std::fs::write(root.join("src/lib.rs"), "").unwrap();
std::fs::write(root.join("src/test.txt"), "").unwrap();
let files = find_files(root, ".rs").unwrap();
assert_eq!(files.len(), 3);
let files = find_files(root, "test").unwrap();
assert_eq!(files.len(), 2);
}
#[test]
fn test_find_files_with_patterns() {
let temp = tempdir().unwrap();
let root = temp.path();
std::fs::write(root.join("README.md"), "").unwrap();
std::fs::write(root.join("test.MD"), "").unwrap(); std::fs::write(root.join("file.txt"), "").unwrap();
crate::utils::fs::ensure_dir(&root.join("hidden")).unwrap();
std::fs::write(root.join("hidden/.secret.md"), "").unwrap();
let files = find_files(root, ".md").unwrap();
assert_eq!(files.len(), 2);
let files = find_files(root, ".MD").unwrap();
assert_eq!(files.len(), 1);
let files = find_files(root, "test").unwrap();
assert_eq!(files.len(), 1);
let files = find_files(root, "secret").unwrap();
assert_eq!(files.len(), 1);
}
}