Skip to main content

provenant/cache/
mod.rs

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