Skip to main content

walker/
filter.rs

1use ignore::overrides::OverrideBuilder;
2use ignore::WalkBuilder;
3use std::path::Path;
4
5/// Options for `WalkBuilder` (gitignore, hidden files, custom globs).
6#[derive(Debug, Clone)]
7pub struct FilterOptions {
8    /// When true, respect `.gitignore` / `.git/info/exclude` (default: true).
9    pub git_ignore: bool,
10    /// When true, respect `.ignore` files (default: true).
11    pub ignore_files: bool,
12    /// When true, skip hidden files and directories (default: true).
13    pub skip_hidden: bool,
14    /// When true, read ignore rules from parent directories (default: true).
15    pub parents: bool,
16    /// Override globs in `gitignore` syntax (e.g. `!*.tmp` or `target/`).
17    pub overrides: Vec<String>,
18}
19
20impl Default for FilterOptions {
21    fn default() -> Self {
22        Self {
23            git_ignore: true,
24            ignore_files: true,
25            skip_hidden: true,
26            parents: true,
27            overrides: Vec::new(),
28        }
29    }
30}
31
32/// Stable hash for [`crate::Checkpoint::config_hash`].
33pub fn config_hash(opts: &FilterOptions) -> u64 {
34    use std::hash::{Hash, Hasher};
35    let mut h = std::collections::hash_map::DefaultHasher::new();
36    opts.git_ignore.hash(&mut h);
37    opts.ignore_files.hash(&mut h);
38    opts.skip_hidden.hash(&mut h);
39    opts.parents.hash(&mut h);
40    for line in &opts.overrides {
41        line.hash(&mut h);
42    }
43    h.finish()
44}
45
46/// Configure a `WalkBuilder` for `root` using `opts`.
47pub fn apply_walk_builder(root: &Path, opts: &FilterOptions) -> Result<WalkBuilder, ignore::Error> {
48    let mut wb = WalkBuilder::new(root);
49    wb.git_ignore(opts.git_ignore)
50        .ignore(opts.ignore_files)
51        .hidden(opts.skip_hidden)
52        .parents(opts.parents);
53
54    if !opts.overrides.is_empty() {
55        let mut ob = OverrideBuilder::new(root);
56        for pat in &opts.overrides {
57            ob.add(pat)?;
58        }
59        wb.overrides(ob.build()?);
60    }
61
62    Ok(wb)
63}