Add ::empty() and Clone to IgnoreFilterer

This commit is contained in:
Félix Saparelli 2022-01-16 14:49:14 +13:00
parent 0618eb45fc
commit f073eeb344
No known key found for this signature in database
GPG Key ID: B948C4BAE44FC474
2 changed files with 40 additions and 22 deletions

View File

@ -132,8 +132,7 @@ pub async fn from_origin(path: impl AsRef<Path>) -> (Vec<IgnoreFile>, Vec<Error>
) )
.await .await
{ {
dirs.add_last_file_to_filter(&mut files, &mut errors) dirs.add_last_file_to_filter(&mut files, &mut errors).await;
.await;
} }
if discover_file( if discover_file(
@ -145,8 +144,7 @@ pub async fn from_origin(path: impl AsRef<Path>) -> (Vec<IgnoreFile>, Vec<Error>
) )
.await .await
{ {
dirs.add_last_file_to_filter(&mut files, &mut errors) dirs.add_last_file_to_filter(&mut files, &mut errors).await;
.await;
} }
if discover_file( if discover_file(
@ -158,8 +156,7 @@ pub async fn from_origin(path: impl AsRef<Path>) -> (Vec<IgnoreFile>, Vec<Error>
) )
.await .await
{ {
dirs.add_last_file_to_filter(&mut files, &mut errors) dirs.add_last_file_to_filter(&mut files, &mut errors).await;
.await;
} }
} }
} }
@ -348,8 +345,13 @@ impl DirTourist {
.await .await
.map_err(|err| Error::new(ErrorKind::Other, err))?; .map_err(|err| Error::new(ErrorKind::Other, err))?;
filter.add_globs(&["/.git", "/.hg", "/.bzr", "/_darcs", "/.fossil-settings"], Some(base.clone())).await filter
.map_err(|err| Error::new(ErrorKind::Other, err))?; .add_globs(
&["/.git", "/.hg", "/.bzr", "/_darcs", "/.fossil-settings"],
Some(base.clone()),
)
.await
.map_err(|err| Error::new(ErrorKind::Other, err))?;
Ok(Self { Ok(Self {
to_visit: vec![base.clone()], to_visit: vec![base.clone()],
@ -443,15 +445,15 @@ impl DirTourist {
pub(crate) async fn add_last_file_to_filter( pub(crate) async fn add_last_file_to_filter(
&mut self, &mut self,
files: &mut Vec<IgnoreFile>, files: &mut Vec<IgnoreFile>,
errors: &mut Vec<Error>, errors: &mut Vec<Error>,
) { ) {
if let Some(ig) = files.last() { if let Some(ig) = files.last() {
if let Err(err) = self.filter.add_file(ig).await { if let Err(err) = self.filter.add_file(ig).await {
errors.push(Error::new(ErrorKind::Other, err)); errors.push(Error::new(ErrorKind::Other, err));
} }
} }
} }
fn must_skip(&self, mut path: &Path) -> bool { fn must_skip(&self, mut path: &Path) -> bool {
if self.to_skip.contains(path) { if self.to_skip.contains(path) {

View File

@ -24,7 +24,7 @@ use super::files::IgnoreFile;
/// ///
/// It implements [`Filterer`] so it can be used directly in another filterer; it is not designed to /// It implements [`Filterer`] so it can be used directly in another filterer; it is not designed to
/// be used as a standalone filterer. /// be used as a standalone filterer.
#[derive(Debug)] #[derive(Clone, Debug)]
pub struct IgnoreFilterer { pub struct IgnoreFilterer {
origin: PathBuf, origin: PathBuf,
builder: Option<GitignoreBuilder>, builder: Option<GitignoreBuilder>,
@ -32,7 +32,22 @@ pub struct IgnoreFilterer {
} }
impl IgnoreFilterer { impl IgnoreFilterer {
/// Create a new empty filterer.
///
/// Prefer [`new()`](IgnoreFilterer::new()) if you have ignore files ready to use.
pub fn empty(origin: impl AsRef<Path>) -> Self {
let origin = origin.as_ref();
Self {
builder: Some(GitignoreBuilder::new(origin)),
origin: origin.to_owned(),
compiled: Gitignore::empty(),
}
}
/// Read ignore files from disk and load them for filtering. /// Read ignore files from disk and load them for filtering.
///
/// Use [`empty()`](IgnoreFilterer::empty()) if you want an empty filterer,
/// or to construct one outside an async environment.
pub async fn new(origin: impl AsRef<Path>, files: &[IgnoreFile]) -> Result<Self, RuntimeError> { pub async fn new(origin: impl AsRef<Path>, files: &[IgnoreFile]) -> Result<Self, RuntimeError> {
let origin = origin.as_ref(); let origin = origin.as_ref();
let _span = trace_span!("build_filterer", ?origin); let _span = trace_span!("build_filterer", ?origin);
@ -159,10 +174,7 @@ impl IgnoreFilterer {
trace!("recompiling globset"); trace!("recompiling globset");
let recompiled = builder let recompiled = builder
.build() .build()
.map_err(|err| RuntimeError::IgnoreFileGlob { .map_err(|err| RuntimeError::IgnoreFileGlob { file, err })?;
file,
err,
})?;
trace!( trace!(
new_ignores=%(recompiled.num_ignores() - pre_ignores), new_ignores=%(recompiled.num_ignores() - pre_ignores),
@ -178,7 +190,11 @@ impl IgnoreFilterer {
/// Adds some globs manually, if the builder is available. /// Adds some globs manually, if the builder is available.
/// ///
/// Does nothing silently otherwise. /// Does nothing silently otherwise.
pub async fn add_globs(&mut self, globs: &[&str], applies_in: Option<PathBuf>) -> Result<(), RuntimeError> { pub async fn add_globs(
&mut self,
globs: &[&str],
applies_in: Option<PathBuf>,
) -> Result<(), RuntimeError> {
if let Some(ref mut builder) = self.builder { if let Some(ref mut builder) = self.builder {
let _span = trace_span!("loading ignore globs", ?globs).entered(); let _span = trace_span!("loading ignore globs", ?globs).entered();
for line in globs { for line in globs {
@ -187,12 +203,12 @@ impl IgnoreFilterer {
} }
trace!(?line, "adding ignore line"); trace!(?line, "adding ignore line");
builder builder.add_line(applies_in.clone(), line).map_err(|err| {
.add_line(applies_in.clone(), line) RuntimeError::IgnoreFileGlob {
.map_err(|err| RuntimeError::IgnoreFileGlob {
file: "manual glob".into(), file: "manual glob".into(),
err, err,
})?; }
})?;
} }
self.recompile("manual glob".into())?; self.recompile("manual glob".into())?;