astmap-core 0.0.2

Core domain types and logic for astmap
Documentation
use std::collections::HashSet;
use std::path::{Path, PathBuf};

use tracing::info;

use crate::error::ScanError;
use crate::port::ScanStore;

/// Remove DB rows for files that no longer exist on disk.
/// Must run after Phase 1 (so we know which files are on disk) and before
/// Phase 2 (so stale files don't become import resolution targets).
pub(super) fn reconcile_deleted_files(
    project_dir: &Path,
    discovered_files: &[PathBuf],
    db: &dyn ScanStore,
) -> Result<(), ScanError> {
    let db_paths = db.get_all_file_paths()?;
    let disk_paths: HashSet<String> = discovered_files
        .iter()
        .filter_map(|p| {
            p.strip_prefix(project_dir)
                .ok()
                .map(|rel| rel.to_string_lossy().to_string())
        })
        .collect();

    for (path, file_id) in &db_paths {
        if !disk_paths.contains(path) {
            info!("removing stale file from index: {}", path);
            // Delete deps first (including incoming refs) to avoid FK violations,
            // then symbols (FTS triggers fire), then file row
            db.delete_deps_for_file(*file_id)?;
            db.delete_symbols_for_file(*file_id)?;
            db.delete_file(*file_id)?;
        }
    }

    Ok(())
}