This commit is contained in:
Félix Saparelli 2022-06-07 20:53:23 +12:00
parent edf023c009
commit b9eef2690e
No known key found for this signature in database
GPG Key ID: B948C4BAE44FC474
4 changed files with 85 additions and 9 deletions

View File

@ -7,3 +7,4 @@ pub use filter::*;
mod files;
mod filter;
pub mod tree;

View File

@ -1,7 +1,3 @@
use git_config::{
file::{from_paths, GitConfig},
values::Path as GitPath,
};
use std::{
collections::HashSet,
env,
@ -9,6 +5,10 @@ use std::{
path::{Path, PathBuf},
};
use git_config::{
file::{from_paths, GitConfig},
values::Path as GitPath,
};
use tokio::fs::{metadata, read_dir};
use tracing::{trace, trace_span};
@ -474,7 +474,7 @@ impl DirTourist {
pub(crate) async fn add_last_file_to_filter(
&mut self,
files: &mut Vec<IgnoreFile>,
files: &mut [IgnoreFile],
errors: &mut Vec<Error>,
) {
if let Some(ig) = files.last() {

View File

@ -88,10 +88,6 @@ impl IgnoreFilterer {
for (file, content) in files_contents.into_iter().flatten() {
let _span = trace_span!("loading ignore file", ?file).entered();
for line in content.lines() {
if line.is_empty() || line.starts_with('#') {
continue;
}
trace!(?line, "adding ignore line");
builder
.add_line(file.applies_in.clone(), line)

79
lib/src/ignore/tree.rs Normal file
View File

@ -0,0 +1,79 @@
//! IgnoreTree manages [GitIgnore] instances for a directory tree.
//!
//! A [GitIgnore] is only meant to be used for files that cover a single
//! directory. That makes it annoying to use when you have ignore files
//! in many directories, and some global ignore files too.
//!
//! This module provides a similar interface, but supports loading
//! ignore files directly for any path, or for the global space.
// This module is a candidate for a new crate.
// TODO: do our own parsing? having all these builders around is meh
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
};
use ignore::{
gitignore::{Gitignore, GitignoreBuilder, Glob},
Error as IgnoreError, Match,
};
/// An interface for many ignore files in a directory tree.
///
/// This is conceptually a tree of [GitIgnore] instances, rooted at the
/// origin, and the matcher methods figure out which one to call on.
#[derive(Debug)]
pub struct IgnoreTree {
origin: PathBuf,
ignores: BTreeMap<PathBuf, GitignoreBuilder>,
compiled: BTreeMap<PathBuf, Gitignore>,
}
impl IgnoreTree {
/// Create a new IgnoreTree at the given origin.
///
/// The origin is the root of the tree which contains ignore files. Adding
/// ignores that are higher up than the origin will silently discard them,
/// as they wouldn't have any effect anyway. To add ignores from global
/// ignore files, use the dedicated method instead of providing their path.
pub fn new(origin: impl AsRef<Path>) -> Self {
let origin = origin.as_ref();
Self {
origin: origin.to_owned(),
ignores: BTreeMap::new(),
compiled: BTreeMap::new(),
}
}
/// Add a line from an ignore file at a particular path.
///
/// The `at` path should be to the directory _containing_ the ignore file,
/// not to the ignore file itself.
pub fn add_local_line(&mut self, at: impl AsRef<Path>, line: &str) -> Result<(), IgnoreError> {
todo!()
}
/// Add a line from an ignore file for the global ignore space.
pub fn add_global_line(&mut self, line: &str) -> Result<(), IgnoreError> {
self.add_local_line("", line)
}
/// Returns the total number of ignore globs.
pub fn num_ignores(&self) -> u64 {
todo!()
}
/// Returns the total number of whitelisted globs.
pub fn num_whitelists(&self) -> u64 {
todo!()
}
/// Returns whether the given path (file or directory) matched a pattern.
// TODO: grow our own return type for this
pub fn matched(&self, path: impl AsRef<Path>, is_dir: bool) -> Match<&Glob> {
// do the "is in tree, check parents, otherwise don't" dance ourselves
todo!()
}
}