Recursively collect all `.php` files under a directory, respecting `.gitignore` rules and skipping hidden directories (`.git`, `.idea`, etc.). Uses the `ignore` crate's `WalkBuilder` for gitignore-aware traversal. This is consistent with the other workspace walkers (`scan_workspace_fallback_full`, `collect_php_files_gitignore`). Used by Go-to-implementation (Phase 5) which walks PSR-4 source di
(dir: &Path, vendor_dir_paths: &[PathBuf])
| 221 | /// Silently skips directories and files that cannot be read (e.g. |
| 222 | /// permission errors, broken symlinks). |
| 223 | pub(crate) fn collect_php_files(dir: &Path, vendor_dir_paths: &[PathBuf]) -> Vec<PathBuf> { |
| 224 | use ignore::WalkBuilder; |
| 225 | |
| 226 | let mut result = Vec::new(); |
| 227 | let vendor_paths: Vec<PathBuf> = vendor_dir_paths.to_vec(); |
| 228 | |
| 229 | let walker = WalkBuilder::new(dir) |
| 230 | .git_ignore(true) |
| 231 | .git_global(true) |
| 232 | .git_exclude(true) |
| 233 | .hidden(true) |
| 234 | .parents(true) |
| 235 | .ignore(true) |
| 236 | .filter_entry(move |entry| { |
| 237 | if entry.file_type().is_some_and(|ft| ft.is_dir()) { |
| 238 | let path = entry.path(); |
| 239 | if vendor_paths.iter().any(|vp| vp == path) { |
| 240 | return false; |
| 241 | } |
| 242 | } |
| 243 | true |
| 244 | }) |
| 245 | .build(); |
| 246 | |
| 247 | for entry in walker.flatten() { |
| 248 | let path = entry.path(); |
| 249 | if path.is_file() && path.extension().is_some_and(|ext| ext == "php") { |
| 250 | result.push(path.to_path_buf()); |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | result |
| 255 | } |
| 256 | |
| 257 | /// Recursively collect all `.php` files under a workspace root, |
| 258 | /// respecting `.gitignore` rules (including nested and global |
no test coverage detected