diff --git a/.gitignore b/.gitignore index 1bf91cda47..3a85a380a7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ book-example/book .vscode tests/dummy_book/book/ +# Ignore Jetbrains specific files. +.idea/ diff --git a/Cargo.lock b/Cargo.lock index 76bae9838e..82be48cce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 974fa90f42..5690cacbaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index bf903f90a7..fe1f188c5c 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -48,6 +48,38 @@ pub fn execute(args: &ArgMatches) -> Result<()> { Ok(()) } +fn remove_ignored_files(book_root: &PathBuf, paths: &[PathBuf]) -> Vec { + 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(book: &MDBook, closure: F) where @@ -96,8 +128,12 @@ where _ => None, } }) - .collect(); + .collect::>(); - closure(paths, &book.root); + let paths = remove_ignored_files(&book.root, &paths[..]); + + if !paths.is_empty() { + closure(paths, &book.root); + } } }