pyoxidizerlib/py_packaging/
filtering.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5/*!
6Utility code for filtering.
7*/
8
9use {
10    anyhow::{anyhow, Result},
11    log::warn,
12    std::{
13        collections::{BTreeMap, BTreeSet},
14        fs::File,
15        io::{BufRead, BufReader},
16        path::Path,
17    },
18};
19
20pub fn read_resource_names_file(path: &Path) -> Result<BTreeSet<String>> {
21    let fh = File::open(path)?;
22
23    let mut res: BTreeSet<String> = BTreeSet::new();
24
25    for line in BufReader::new(fh).lines() {
26        let line = line?;
27
28        if line.starts_with('#') || line.is_empty() {
29            continue;
30        }
31
32        res.insert(line);
33    }
34
35    Ok(res)
36}
37
38pub fn resolve_resource_names_from_files(
39    files: &[&Path],
40    glob_files: &[&str],
41) -> Result<BTreeSet<String>> {
42    let mut include_names = BTreeSet::new();
43
44    for path in files {
45        let new_names = read_resource_names_file(path)?;
46        include_names.extend(new_names);
47    }
48
49    for pattern in glob_files {
50        let mut new_names = BTreeSet::new();
51
52        for entry in glob::glob(pattern)? {
53            new_names.extend(read_resource_names_file(&entry?)?);
54        }
55
56        if new_names.is_empty() {
57            return Err(anyhow!(
58                "glob filter resolves to empty set; are you sure the glob pattern is correct?"
59            ));
60        }
61
62        include_names.extend(new_names);
63    }
64
65    Ok(include_names)
66}
67
68pub fn filter_btreemap<V>(m: &mut BTreeMap<String, V>, f: &BTreeSet<String>) {
69    let keys: Vec<String> = m.keys().cloned().collect();
70
71    for key in keys {
72        if !f.contains(&key) {
73            warn!("removing {}", key);
74            m.remove(&key);
75        }
76    }
77}