git_stack/git/
protect.rs

1#[derive(Clone, Debug)]
2pub struct ProtectedBranches {
3    ignores: ignore::gitignore::Gitignore,
4}
5
6impl ProtectedBranches {
7    pub fn new<'p>(patterns: impl IntoIterator<Item = &'p str>) -> eyre::Result<Self> {
8        let mut ignores = ignore::gitignore::GitignoreBuilder::new("");
9        for pattern in patterns {
10            ignores.add_line(None, pattern)?;
11        }
12        let ignores = ignores.build()?;
13        Ok(Self { ignores })
14    }
15
16    pub fn is_protected(&self, name: &str) -> bool {
17        let name_match = self.ignores.matched_path_or_any_parents(name, false);
18        match name_match {
19            ignore::Match::None => false,
20            ignore::Match::Ignore(glob) => {
21                log::trace!("`{}` is ignored by {:?}", name, glob.original());
22                true
23            }
24            ignore::Match::Whitelist(glob) => {
25                log::trace!("`{}` is allowed by {:?}", name, glob.original());
26                false
27            }
28        }
29    }
30}
31
32#[cfg(test)]
33mod test {
34    use super::*;
35
36    #[test]
37    fn empty_allows_all() {
38        let protect = ProtectedBranches::new(None).unwrap();
39        assert!(!protect.is_protected("main"));
40    }
41
42    #[test]
43    fn protect_branch() {
44        let protect = ProtectedBranches::new(Some("main")).unwrap();
45        assert!(protect.is_protected("main"));
46        assert!(!protect.is_protected("feature"));
47    }
48
49    #[test]
50    fn negation_patterns() {
51        let protect = ProtectedBranches::new(vec!["v*", "!very"]).unwrap();
52        assert!(protect.is_protected("v1.0.0"));
53        assert!(!protect.is_protected("very"));
54        assert!(!protect.is_protected("feature"));
55    }
56
57    #[test]
58    fn folders() {
59        let protect = ProtectedBranches::new(vec!["release/"]).unwrap();
60        assert!(!protect.is_protected("release"));
61        assert!(protect.is_protected("release/v1.0.0"));
62        assert!(!protect.is_protected("feature"));
63    }
64}