Include .gitignores in subdirectories

This commit is contained in:
Chris Nicholls 2020-03-06 10:28:29 +00:00
parent 5843deb573
commit 0175e071e1
3 changed files with 31 additions and 23 deletions

7
Cargo.lock generated
View File

@ -312,7 +312,7 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -425,7 +425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.2.9"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -446,6 +446,7 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
"notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -547,7 +548,7 @@ dependencies = [
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"

View File

@ -31,6 +31,7 @@ lazy_static = "1.1.0"
log = "0.4.4"
notify = "4.0.13"
derive_builder = "0.9.0"
walkdir = "2.3.1"
[dependencies.clap]
version = "2.32.0"

View File

@ -1,11 +1,13 @@
extern crate globset;
extern crate walkdir;
use globset::{GlobBuilder, GlobSet, GlobSetBuilder};
use std::collections::HashSet;
use std::fs;
use std::io;
use std::io::Read;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
pub struct Gitignore {
files: Vec<GitignoreFile>,
@ -43,39 +45,43 @@ enum MatchResult {
pub fn load(paths: &[PathBuf]) -> Gitignore {
let mut files = vec![];
let mut checked_dirs = HashSet::new();
for path in paths {
let mut p = path.to_owned();
loop {
if !checked_dirs.contains(&p) {
checked_dirs.insert(p.clone());
let gitignore_path = p.join(".gitignore");
if gitignore_path.exists() {
if let Ok(f) = GitignoreFile::new(&gitignore_path) {
debug!("Loaded {:?}", gitignore_path);
files.push(f);
} else {
debug!("Unable to load {:?}", gitignore_path);
}
}
}
// scan parent directories up to a root .git folder
let top_level_git_dir = loop {
// Stop if we see a .git directory
if let Ok(metadata) = p.join(".git").metadata() {
if metadata.is_dir() {
break;
break Some(path);
}
}
if p.parent().is_none() {
break;
break None;
}
};
p.pop();
if let Some(root) = top_level_git_dir {
// scan in subdirectories
for entry in WalkDir::new(root)
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())
.filter(|e| e.file_name() == ".gitignore")
{
let gitignore_path = entry.path();
if let Ok(f) = GitignoreFile::new(&gitignore_path) {
debug!("Loaded {:?}", gitignore_path);
files.push(f);
} else {
debug!("Unable to load {:?}", gitignore_path);
}
}
}
p.pop();
}
Gitignore::new(files)