2021-04-25 08:59:03 +03:00
|
|
|
use ignore::gitignore::Gitignore;
|
2021-04-27 01:46:06 +03:00
|
|
|
use std::{ffi::OsStr, path::Path, sync::Arc};
|
2021-04-25 08:59:03 +03:00
|
|
|
|
|
|
|
pub enum IgnoreStack {
|
|
|
|
None,
|
|
|
|
Some {
|
|
|
|
base: Arc<Path>,
|
|
|
|
ignore: Arc<Gitignore>,
|
|
|
|
parent: Arc<IgnoreStack>,
|
|
|
|
},
|
|
|
|
All,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IgnoreStack {
|
|
|
|
pub fn none() -> Arc<Self> {
|
|
|
|
Arc::new(Self::None)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn all() -> Arc<Self> {
|
|
|
|
Arc::new(Self::All)
|
|
|
|
}
|
|
|
|
|
2021-04-26 16:26:16 +03:00
|
|
|
pub fn is_all(&self) -> bool {
|
|
|
|
matches!(self, IgnoreStack::All)
|
|
|
|
}
|
|
|
|
|
2021-04-25 08:59:03 +03:00
|
|
|
pub fn append(self: Arc<Self>, base: Arc<Path>, ignore: Arc<Gitignore>) -> Arc<Self> {
|
|
|
|
match self.as_ref() {
|
|
|
|
IgnoreStack::All => self,
|
|
|
|
_ => Arc::new(Self::Some {
|
|
|
|
base,
|
|
|
|
ignore,
|
|
|
|
parent: self,
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_path_ignored(&self, path: &Path, is_dir: bool) -> bool {
|
2021-04-27 01:46:06 +03:00
|
|
|
if is_dir && path.file_name() == Some(OsStr::new(".git")) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-25 08:59:03 +03:00
|
|
|
match self {
|
2021-04-26 16:26:16 +03:00
|
|
|
Self::None => false,
|
|
|
|
Self::All => true,
|
2021-04-25 08:59:03 +03:00
|
|
|
Self::Some {
|
|
|
|
base,
|
|
|
|
ignore,
|
|
|
|
parent: prev,
|
2021-04-26 16:26:16 +03:00
|
|
|
} => match ignore.matched(path.strip_prefix(base).unwrap(), is_dir) {
|
|
|
|
ignore::Match::None => prev.is_path_ignored(path, is_dir),
|
|
|
|
ignore::Match::Ignore(_) => true,
|
|
|
|
ignore::Match::Whitelist(_) => false,
|
|
|
|
},
|
2021-04-25 08:59:03 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|