(
project_root: &Path,
dir_name: &str,
follow_symlinks: bool,
seen_data_dirs: &mut HashSet<PathBuf>,
stores: &mut Vec<StoreInventory>,
skipped: &mut Vec<SkippedPath>,
role:
| 247 | } |
| 248 | |
| 249 | async fn inspect_data_dir_candidate( |
| 250 | project_root: &Path, |
| 251 | dir_name: &str, |
| 252 | follow_symlinks: bool, |
| 253 | seen_data_dirs: &mut HashSet<PathBuf>, |
| 254 | stores: &mut Vec<StoreInventory>, |
| 255 | skipped: &mut Vec<SkippedPath>, |
| 256 | role: StoreRole, |
| 257 | ) -> Result<()> { |
| 258 | let mut data_dir = project_root.join(dir_name); |
| 259 | let Ok(meta) = std::fs::symlink_metadata(&data_dir) else { |
| 260 | return Ok(()); |
| 261 | }; |
| 262 | if meta.file_type().is_symlink() { |
| 263 | if !follow_symlinks { |
| 264 | skipped.push(SkippedPath { |
| 265 | path: data_dir, |
| 266 | reason: "symlink".to_string(), |
| 267 | }); |
| 268 | return Ok(()); |
| 269 | } |
| 270 | if !data_dir.is_dir() { |
| 271 | return Ok(()); |
| 272 | } |
| 273 | data_dir = data_dir.canonicalize().unwrap_or(data_dir); |
| 274 | } else if !meta.is_dir() { |
| 275 | return Ok(()); |
| 276 | } |
| 277 | let key = data_dir.canonicalize().unwrap_or_else(|_| data_dir.clone()); |
| 278 | if !seen_data_dirs.insert(key) { |
| 279 | return Ok(()); |
| 280 | } |
| 281 | let brand = StoreBrand::TraceDecay; |
| 282 | let db_path = data_dir.join(db_filename(&data_dir)); |
| 283 | let store = inspect_project_store( |
| 284 | project_root, |
| 285 | &data_dir, |
| 286 | db_path, |
| 287 | brand, |
| 288 | role, |
| 289 | follow_symlinks, |
| 290 | skipped, |
| 291 | ) |
| 292 | .await?; |
| 293 | stores.push(store); |
| 294 | Ok(()) |
| 295 | } |
| 296 | |
| 297 | async fn inspect_project_store( |
| 298 | project_root: &Path, |
no test coverage detected