feat: add flag to choose backend

This commit is contained in:
KFears 2023-12-06 20:16:22 +04:00
parent f427f24586
commit 43464c6d82
No known key found for this signature in database
2 changed files with 84 additions and 30 deletions

View File

@ -9,6 +9,8 @@ use mdbook::errors::*;
use mdbook::utils; use mdbook::utils;
use mdbook::utils::fs::get_404_output_file; use mdbook::utils::fs::get_404_output_file;
use mdbook::MDBook; use mdbook::MDBook;
use notify::PollWatcher;
use notify::RecommendedWatcher;
use std::net::{SocketAddr, ToSocketAddrs}; use std::net::{SocketAddr, ToSocketAddrs};
use std::path::PathBuf; use std::path::PathBuf;
use tokio::sync::broadcast; use tokio::sync::broadcast;
@ -43,6 +45,9 @@ pub fn make_subcommand() -> Command {
.help("Port to use for HTTP connections"), .help("Port to use for HTTP connections"),
) )
.arg_open() .arg_open()
.arg(arg!(--compat "Watch files in compatibility mode.\n\
Use this if your environment doesn't support filesystem events (Windows, Docker, NFS),
or if you encounter issues otherwise"))
} }
// Serve command implementation // Serve command implementation
@ -97,23 +102,48 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
} }
#[cfg(feature = "watch")] #[cfg(feature = "watch")]
watch::trigger_on_change(&book, move |paths, book_dir| { let polling = args.get_flag("compat");
info!("Files changed: {:?}", paths);
info!("Building book...");
// FIXME: This area is really ugly because we need to re-set livereload :( #[cfg(feature = "watch")]
let result = MDBook::load(book_dir).and_then(|mut b| { if polling {
update_config(&mut b); debug!("Using PollWatcher backend");
b.build() watch::trigger_on_change::<_, PollWatcher>(&book, move |paths, book_dir| {
info!("Files changed: {:?}", paths);
info!("Building book...");
// FIXME: This area is really ugly because we need to re-set livereload :(
let result = MDBook::load(book_dir).and_then(|mut b| {
update_config(&mut b);
b.build()
});
if let Err(e) = result {
error!("Unable to load the book");
utils::log_backtrace(&e);
} else {
let _ = tx.send(Message::text("reload"));
}
}); });
} else {
debug!("Using RecommendWatcher backend");
watch::trigger_on_change::<_, RecommendedWatcher>(&book, move |paths, book_dir| {
info!("Files changed: {:?}", paths);
info!("Building book...");
if let Err(e) = result { // FIXME: This area is really ugly because we need to re-set livereload :(
error!("Unable to load the book"); let result = MDBook::load(book_dir).and_then(|mut b| {
utils::log_backtrace(&e); update_config(&mut b);
} else { b.build()
let _ = tx.send(Message::text("reload")); });
}
}); if let Err(e) = result {
error!("Unable to load the book");
utils::log_backtrace(&e);
} else {
let _ = tx.send(Message::text("reload"));
}
});
}
let _ = thread_handle.join(); let _ = thread_handle.join();

View File

@ -4,6 +4,9 @@ use ignore::gitignore::Gitignore;
use mdbook::errors::Result; use mdbook::errors::Result;
use mdbook::utils; use mdbook::utils;
use mdbook::MDBook; use mdbook::MDBook;
use notify::PollWatcher;
use notify::RecommendedWatcher;
use notify::Watcher;
use notify_debouncer_mini::Config; use notify_debouncer_mini::Config;
use pathdiff::diff_paths; use pathdiff::diff_paths;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -18,6 +21,9 @@ pub fn make_subcommand() -> Command {
.arg_dest_dir() .arg_dest_dir()
.arg_root_dir() .arg_root_dir()
.arg_open() .arg_open()
.arg(arg!(--compat "Watch files in compatibility mode.\n\
Use this if your environment doesn't support filesystem events (Windows, Docker, NFS),
or if you encounter issues otherwise"))
} }
// Watch command implementation // Watch command implementation
@ -42,18 +48,37 @@ pub fn execute(args: &ArgMatches) -> Result<()> {
open(path); open(path);
} }
trigger_on_change(&book, |paths, book_dir| { let polling = args.get_flag("compat");
info!("Files changed: {:?}\nBuilding book...\n", paths);
let result = MDBook::load(book_dir).and_then(|mut b| {
update_config(&mut b);
b.build()
});
if let Err(e) = result { if polling {
error!("Unable to build the book"); debug!("Using PollWatcher backend");
utils::log_backtrace(&e); trigger_on_change::<_, PollWatcher>(&book, |paths, book_dir| {
} info!("Files changed: {:?}\nBuilding book...\n", paths);
}); let result = MDBook::load(book_dir).and_then(|mut b| {
update_config(&mut b);
b.build()
});
if let Err(e) = result {
error!("Unable to build the book");
utils::log_backtrace(&e);
}
});
} else {
debug!("Using RecommendWatcher backend");
trigger_on_change::<_, RecommendedWatcher>(&book, |paths, book_dir| {
info!("Files changed: {:?}\nBuilding book...\n", paths);
let result = MDBook::load(book_dir).and_then(|mut b| {
update_config(&mut b);
b.build()
});
if let Err(e) = result {
error!("Unable to build the book");
utils::log_backtrace(&e);
}
});
};
Ok(()) Ok(())
} }
@ -110,9 +135,10 @@ fn filter_ignored_files(ignore: Gitignore, paths: &[PathBuf]) -> Vec<PathBuf> {
} }
/// Calls the closure when a book source file is changed, blocking indefinitely. /// Calls the closure when a book source file is changed, blocking indefinitely.
pub fn trigger_on_change<F>(book: &MDBook, closure: F) pub fn trigger_on_change<F, W>(book: &MDBook, closure: F)
where where
F: Fn(Vec<PathBuf>, &Path), F: Fn(Vec<PathBuf>, &Path),
W: 'static + Watcher + Send,
{ {
use notify::RecursiveMode::*; use notify::RecursiveMode::*;
@ -125,10 +151,8 @@ where
.with_timeout(Duration::from_secs(1)) .with_timeout(Duration::from_secs(1))
.with_notify_config(backend_config); .with_notify_config(backend_config);
let mut debouncer = match notify_debouncer_mini::new_debouncer_opt::<_, notify::PollWatcher>( let mut debouncer = match notify_debouncer_mini::new_debouncer_opt::<_, W>(debouncer_config, tx)
debouncer_config, {
tx,
) {
Ok(d) => d, Ok(d) => d,
Err(e) => { Err(e) => {
error!("Error while trying to watch the files:\n\n\t{:?}", e); error!("Error while trying to watch the files:\n\n\t{:?}", e);