Skip to main content

provenant/cache/
mod.rs

1use std::path::Path;
2
3use glob::Pattern;
4
5mod config;
6mod incremental;
7mod io;
8pub(crate) mod locking;
9
10pub use config::{CACHE_DIR_ENV_VAR, CacheConfig, DEFAULT_CACHE_DIR_NAME};
11pub use incremental::{
12    IncrementalManifest, IncrementalManifestEntry, incremental_manifest_path,
13    load_incremental_manifest, manifest_entry_matches_path, metadata_fingerprint,
14    write_incremental_manifest,
15};
16pub(crate) use io::write_bytes_atomically;
17
18pub fn build_collection_exclude_patterns(scan_root: &Path, cache_root: &Path) -> Vec<Pattern> {
19    let mut patterns = Vec::new();
20
21    for vcs_dir in [".git", ".hg", ".svn"] {
22        for pattern in [vcs_dir.to_string(), format!("{vcs_dir}/**")] {
23            if let Ok(pattern) = Pattern::new(&pattern) {
24                patterns.push(pattern);
25            }
26        }
27    }
28
29    for pattern in [".gitignore", "**/.gitignore"] {
30        if let Ok(pattern) = Pattern::new(pattern) {
31            patterns.push(pattern);
32        }
33    }
34
35    if let Ok(relative_cache_root) = cache_root.strip_prefix(scan_root)
36        && !relative_cache_root.as_os_str().is_empty()
37    {
38        for path in [cache_root.to_path_buf(), relative_cache_root.to_path_buf()] {
39            let normalized = path.to_string_lossy().replace('\\', "/");
40            let escaped = Pattern::escape(&normalized);
41            for pattern in [escaped.clone(), format!("{escaped}/**")] {
42                if let Ok(pattern) = Pattern::new(&pattern) {
43                    patterns.push(pattern);
44                }
45            }
46        }
47    }
48
49    patterns
50}