Added support for gitignore files. (#1044)

* Added support for gitignore files.
The watch command will now ignore files based on gitignore. This can be useful for when your editor creates cache or swap files.

* Ran cargo fmt.

* Made the code a bit tidier based on input from other Rust programmers.
Changed the type of the closure back to use PathBuf, not &PathBuf.
Reduced nesting.
This commit is contained in:
Kim Hå 2019-10-04 14:59:17 +02:00 committed by Dylan DPC
parent a6f317e352
commit 8e8e53ae15
4 changed files with 58 additions and 3 deletions

2
.gitignore vendored
View File

@ -9,3 +9,5 @@ book-example/book
.vscode
tests/dummy_book/book/
# Ignore Jetbrains specific files.
.idea/

16
Cargo.lock generated
View File

@ -385,6 +385,19 @@ dependencies = [
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gitignore"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glob"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "handlebars"
version = "2.0.2"
@ -659,6 +672,7 @@ dependencies = [
"elasticlunr-rs 2.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gitignore 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"handlebars 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"iron 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1703,6 +1717,8 @@ dependencies = [
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum getopts 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
"checksum gitignore 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5beed3b526478bebc1dd164b7aa770ae709f918a7b978fcb4afdaf3bbee8dfd"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
"checksum handlebars 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "91ef1ac30f2eaaa2b835fce73c57091cb6b9fc62b7eef285efbf980b0f20001b"
"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353"
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"

View File

@ -38,6 +38,7 @@ toml-query = "0.9"
# Watch feature
notify = { version = "4.0", optional = true }
gitignore = { version = "1.0", optional = true }
# Serve feature
iron = { version = "0.6", optional = true }
@ -57,7 +58,7 @@ walkdir = "2.0"
default = ["output", "watch", "serve", "search"]
debug = []
output = []
watch = ["notify"]
watch = ["notify", "gitignore"]
serve = ["iron", "staticfile", "ws"]
search = ["elasticlunr-rs", "ammonia"]

View File

@ -48,6 +48,38 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
Ok(())
}
fn remove_ignored_files(book_root: &PathBuf, paths: &[PathBuf]) -> Vec<PathBuf> {
if paths.is_empty() {
return vec![];
}
let gitignore_path = book_root.with_file_name(".gitignore");
match gitignore::File::new(gitignore_path.as_path()) {
Ok(exclusion_checker) => paths
.iter()
.filter(|path| match exclusion_checker.is_excluded(path) {
Ok(exclude) => !exclude,
Err(error) => {
warn!(
"Unable to determine if {:?} is excluded: {:?}. Including it.",
&path, error
);
true
}
})
.map(|path| path.to_path_buf())
.collect(),
Err(error) => {
warn!(
"Unable to read gitignore file at {:?} file: {:?}. All files will be allowed.",
gitignore_path, error
);
paths.iter().map(|path| path.to_path_buf()).collect()
}
}
}
/// Calls the closure when a book source file is changed, blocking indefinitely.
pub fn trigger_on_change<F>(book: &MDBook, closure: F)
where
@ -96,8 +128,12 @@ where
_ => None,
}
})
.collect();
.collect::<Vec<_>>();
closure(paths, &book.root);
let paths = remove_ignored_files(&book.root, &paths[..]);
if !paths.is_empty() {
closure(paths, &book.root);
}
}
}