From 0a43f618e78a9a5c72d93c7c626405aa17c9770e Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Thu, 26 Dec 2024 04:49:44 -0800 Subject: [PATCH] Add optional arg to `serve` for extra paths to watch for changes (#2745) * Add optional arg to serve for extra paths to watch for changes * Address feedback --- src/cli.rs | 4 ++++ src/cmd/serve.rs | 27 +++++++++++++++++++++++++-- src/fs_utils.rs | 4 +++- src/main.rs | 2 ++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 1329edff4d..c3f68a493c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -89,6 +89,10 @@ pub enum Command { /// Default append port to the base url. #[clap(long)] no_port_append: bool, + + /// Extra path to watch for changes, relative to the project root. + #[clap(long)] + extra_watch_path: Vec, }, /// Try to build the project without rendering it. Checks links diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 84b8b9c8a0..2ab661b0f3 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -430,6 +430,7 @@ pub fn serve( fast_rebuild: bool, no_port_append: bool, utc_offset: UtcOffset, + extra_watch_paths: Vec, ) -> Result<()> { let start = Instant::now(); let (mut site, bind_address, constructed_base_url) = create_new_site( @@ -462,8 +463,8 @@ pub fn serve( // An array of (path, WatchMode, RecursiveMode) where the path is watched for changes, // the WatchMode value indicates whether this path must exist for zola serve to operate, // and the RecursiveMode value indicates whether to watch nested directories. - let watch_this = vec![ - // The first entry is ultimtely to watch config.toml in a more robust manner on Linux when + let mut watch_this = vec![ + // The first entry is ultimately to watch config.toml in a more robust manner on Linux when // the file changes by way of a caching strategy used by editors such as vim. // https://github.com/getzola/zola/issues/2266 (root_dir_str, WatchMode::Required, RecursiveMode::NonRecursive), @@ -473,6 +474,11 @@ pub fn serve( ("templates", WatchMode::Optional, RecursiveMode::Recursive), ("themes", WatchMode::Condition(site.config.theme.is_some()), RecursiveMode::Recursive), ]; + watch_this.extend( + extra_watch_paths + .iter() + .map(|path| (path.as_str(), WatchMode::Required, RecursiveMode::Recursive)), + ); // Setup watchers let (tx, rx) = channel(); @@ -810,6 +816,23 @@ pub fn serve( site = s; } } + ChangeKind::ExtraPath => { + let full_paths: Vec<&PathBuf> = + change_group.iter().map(|(_, p, _)| p).collect(); + let combined_paths = full_paths + .iter() + .map(|p| p.display().to_string()) + .collect::>() + .join(", "); + console::info(&format!( + "-> {combined_paths} changed. Recreating whole site." + )); + + // We can't know exactly what to update when a user provides the path. + if let Some(s) = recreate_site() { + site = s; + } + } }; messages::report_elapsed_time(start); } diff --git a/src/fs_utils.rs b/src/fs_utils.rs index 6530de437f..421380a226 100644 --- a/src/fs_utils.rs +++ b/src/fs_utils.rs @@ -17,6 +17,8 @@ pub enum ChangeKind { StaticFiles, Sass, Config, + /// A change in one of the extra paths to watch provided by the user. + ExtraPath, } /// This enum abstracts over the fine-grained group of enums in `notify`. @@ -160,7 +162,7 @@ fn detect_change_kind(pwd: &Path, path: &Path, config_path: &Path) -> (ChangeKin } else if path == config_path { ChangeKind::Config } else { - unreachable!("Got a change in an unexpected path: {}", partial_path.display()); + ChangeKind::ExtraPath }; (change_kind, partial_path) diff --git a/src/main.rs b/src/main.rs index 4e96a73253..88b3e0e617 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,6 +86,7 @@ fn main() { open, fast, no_port_append, + extra_watch_path, } => { if port != 1111 && !port_is_available(port) { console::error("The requested port is not available"); @@ -114,6 +115,7 @@ fn main() { fast, no_port_append, UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC), + extra_watch_path, ) { messages::unravel_errors("Failed to serve the site", &e); std::process::exit(1);