From 1ac26023603e26401123fa352ccd74ce46b93f77 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Sun, 1 Jan 2017 15:59:22 -0800 Subject: [PATCH 1/2] Update to notify 3.0 notify now does its own event debouncing, so it's no longer necessary for mdbook to do this manually. --- Cargo.toml | 2 +- src/bin/mdbook.rs | 110 ++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f44b31d4..cc2f11ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ toml = { version = "0.2", features = ["serde"] } open = "1.1" # Watch feature -notify = { version = "2.5.5", optional = true } +notify = { version = "3.0", optional = true } time = { version = "0.1.34", optional = true } crossbeam = { version = "0.2.8", optional = true } diff --git a/src/bin/mdbook.rs b/src/bin/mdbook.rs index 3a82bf3e..27d5313d 100644 --- a/src/bin/mdbook.rs +++ b/src/bin/mdbook.rs @@ -35,6 +35,8 @@ use clap::{App, ArgMatches, SubCommand, AppSettings}; #[cfg(feature = "watch")] use notify::Watcher; #[cfg(feature = "watch")] +use std::time::Duration; +#[cfg(feature = "watch")] use std::sync::mpsc::channel; @@ -187,15 +189,13 @@ fn watch(args: &ArgMatches) -> Result<(), Box> { open(book.get_dest().join("index.html")); } - trigger_on_change(&mut book, |event, book| { - if let Some(path) = event.path { - println!("File changed: {:?}\nBuilding book...\n", path); - match book.build() { - Err(e) => println!("Error while building: {:?}", e), - _ => {}, - } - println!(""); + trigger_on_change(&mut book, |path, book| { + println!("File changed: {:?}\nBuilding book...\n", path); + match book.build() { + Err(e) => println!("Error while building: {:?}", e), + _ => {}, } + println!(""); }); Ok(()) @@ -258,15 +258,13 @@ fn serve(args: &ArgMatches) -> Result<(), Box> { open(format!("http://{}", address)); } - trigger_on_change(&mut book, move |event, book| { - if let Some(path) = event.path { - println!("File changed: {:?}\nBuilding book...\n", path); - match book.build() { - Err(e) => println!("Error while building: {:?}", e), - _ => broadcaster.send(RELOAD_COMMAND).unwrap(), - } - println!(""); + trigger_on_change(&mut book, move |path, book| { + println!("File changed: {:?}\nBuilding book...\n", path); + match book.build() { + Err(e) => println!("Error while building: {:?}", e), + _ => broadcaster.send(RELOAD_COMMAND).unwrap(), } + println!(""); }); Ok(()) @@ -307,53 +305,51 @@ fn open>(path: P) { // Calls the closure when a book source file is changed. This is blocking! #[cfg(feature = "watch")] fn trigger_on_change(book: &mut MDBook, closure: F) -> () - where F: Fn(notify::Event, &mut MDBook) -> () + where F: Fn(&Path, &mut MDBook) -> () { + use notify::RecursiveMode::*; + use notify::DebouncedEvent::*; + // Create a channel to receive the events. let (tx, rx) = channel(); - let w: Result = notify::Watcher::new(tx); - - match w { - Ok(mut watcher) => { - // Add the source directory to the watcher - if let Err(e) = watcher.watch(book.get_src()) { - println!("Error while watching {:?}:\n {:?}", book.get_src(), e); - ::std::process::exit(0); - }; - - // Add the book.json file to the watcher if it exists, because it's not - // located in the source directory - if let Err(_) = watcher.watch(book.get_root().join("book.json")) { - // do nothing if book.json is not found - } - - let mut previous_time = time::get_time(); - - println!("\nListening for changes...\n"); - - loop { - match rx.recv() { - Ok(event) => { - // Skip the event if an event has already been issued in the last second - let time = time::get_time(); - if time - previous_time < time::Duration::seconds(1) { - continue; - } else { - previous_time = time; - } - - closure(event, book); - }, - Err(e) => { - println!("An error occured: {:?}", e); - }, - } - } - }, + let mut watcher = match notify::watcher(tx, Duration::from_secs(1)) { + Ok(w) => w, Err(e) => { println!("Error while trying to watch the files:\n\n\t{:?}", e); ::std::process::exit(0); - }, + } + }; + + // Add the source directory to the watcher + if let Err(e) = watcher.watch(book.get_src(), Recursive) { + println!("Error while watching {:?}:\n {:?}", book.get_src(), e); + ::std::process::exit(0); + }; + + // Add the book.{json,toml} file to the watcher if it exists, because it's not + // located in the source directory + if let Err(_) = watcher.watch(book.get_root().join("book.json"), NonRecursive) { + // do nothing if book.json is not found + } + println!("\nListening for changes...\n"); + + loop { + match rx.recv() { + Ok(event) => match event { + NoticeWrite(path) | + NoticeRemove(path) | + Create(path) | + Write(path) | + Remove(path) | + Rename(_, path) => { + closure(&path, book); + } + _ => {} + }, + Err(e) => { + println!("An error occured: {:?}", e); + }, + } } } From c7b4147ba73830c7532e69fad98a9f22d5151102 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Sun, 1 Jan 2017 16:00:21 -0800 Subject: [PATCH 2/2] Watch both book.json and book.toml --- src/bin/mdbook.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bin/mdbook.rs b/src/bin/mdbook.rs index 27d5313d..33b22913 100644 --- a/src/bin/mdbook.rs +++ b/src/bin/mdbook.rs @@ -332,6 +332,10 @@ fn trigger_on_change(book: &mut MDBook, closure: F) -> () if let Err(_) = watcher.watch(book.get_root().join("book.json"), NonRecursive) { // do nothing if book.json is not found } + if let Err(_) = watcher.watch(book.get_root().join("book.toml"), NonRecursive) { + // do nothing if book.toml is not found + } + println!("\nListening for changes...\n"); loop {