ripsecrets/
ignore_info.rs

1use std::collections::HashSet;
2use std::env;
3use std::error::Error;
4use std::fs;
5use std::io::Write;
6use std::option::Option;
7use std::path::PathBuf;
8
9use ignore::gitignore::Gitignore;
10use tempfile::NamedTempFile;
11
12pub struct IgnoreInfo {
13    pub ignore_file_path: Option<PathBuf>,
14    pub ignore_matcher: Option<Gitignore>,
15    pub ignore_secrets: HashSet<Vec<u8>>,
16
17    _tmp_file: Option<NamedTempFile>,
18}
19
20const SECRETS_SECTION_HEADER: &str = "[secrets]\n";
21
22pub fn get_ignore_info() -> Result<IgnoreInfo, Box<dyn Error>> {
23    /*
24        - check for the existence of .secretsignore
25        - if it exists, and is only file ignores, add return it directly
26        - if it contains only secrets, only add secret exclusions
27        - if it contains both, write file ignores to a temp file and add it
28    */
29
30    let mut secrets_ignore_filename = env::current_dir()?;
31
32    secrets_ignore_filename.push(".secretsignore");
33
34    let mut maybe_ignore_file_path: Option<PathBuf> = None;
35    let mut maybe_ignore_matcher: Option<Gitignore> = None;
36    let mut maybe_tmp_file: Option<NamedTempFile> = None;
37    let mut ignore_secrets = HashSet::<Vec<u8>>::new();
38
39    if secrets_ignore_filename.exists() {
40        let ignore_contents = fs::read_to_string(&secrets_ignore_filename)?;
41        if ignore_contents.contains(SECRETS_SECTION_HEADER) {
42            let components = ignore_contents
43                .split(SECRETS_SECTION_HEADER)
44                .collect::<Vec<&str>>();
45            if !components[0].is_empty() {
46                let mut tmp_file = NamedTempFile::new()?;
47                tmp_file.write_all(components[0].as_bytes())?;
48                maybe_ignore_file_path = Some(PathBuf::from(tmp_file.path()));
49                maybe_ignore_matcher = Some(Gitignore::new(tmp_file.path()).0);
50                maybe_tmp_file = Some(tmp_file);
51            }
52            for secret in components[1].split('\n') {
53                if !secret.is_empty() && !secret.starts_with('#') {
54                    // lines start with a # are comments
55
56                    ignore_secrets.insert(Vec::from(secret.as_bytes()));
57                }
58            }
59        } else {
60            maybe_ignore_file_path = Some(secrets_ignore_filename.clone());
61            maybe_ignore_matcher = Some(Gitignore::new(secrets_ignore_filename.clone()).0);
62        }
63    }
64
65    return Ok(IgnoreInfo {
66        ignore_file_path: maybe_ignore_file_path,
67        ignore_matcher: maybe_ignore_matcher,
68        ignore_secrets,
69        _tmp_file: maybe_tmp_file,
70    });
71}