From 660b57e1fb5b2bc99b3db0dce48b8f903ab08cc6 Mon Sep 17 00:00:00 2001 From: Rob Parrett Date: Fri, 20 Dec 2024 06:37:12 -0700 Subject: [PATCH] Add optional config for extra paths to watch for changes --- components/config/src/config/mod.rs | 18 ++++++++++++++++++ .../getting-started/configuration.md | 4 ++++ src/cmd/serve.rs | 14 +++++++++++++- src/fs_utils.rs | 3 ++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/components/config/src/config/mod.rs b/components/config/src/config/mod.rs index 88d949fc21..4dbe4f51fe 100644 --- a/components/config/src/config/mod.rs +++ b/components/config/src/config/mod.rs @@ -102,6 +102,8 @@ pub struct Config { pub generate_sitemap: bool, /// Enables the generation of robots.txt pub generate_robots_txt: bool, + /// A list of extra paths to watch for changes + pub extra_watch_paths: Vec, } #[derive(Serialize)] @@ -123,6 +125,7 @@ pub struct SerializedConfig<'a> { search: search::SerializedSearch<'a>, generate_sitemap: bool, generate_robots_txt: bool, + extra_watch_paths: &'a [String], } impl Config { @@ -340,6 +343,7 @@ impl Config { search: self.search.serialize(), generate_sitemap: self.generate_sitemap, generate_robots_txt: self.generate_robots_txt, + extra_watch_paths: &self.extra_watch_paths, } } } @@ -405,6 +409,7 @@ impl Default for Config { extra: HashMap::new(), generate_sitemap: true, generate_robots_txt: true, + extra_watch_paths: Vec::new(), } } } @@ -804,6 +809,19 @@ ignored_files = ["*.{graphml,iso}", "*.py?", "**/{target,temp_folder}"] assert!(g.is_match("content/poetry/zen.py2")); } + #[test] + fn non_empty_extra_watch_paths_results_in_vector_of_extra_watch_paths() { + let config_str = r#" +title = "My site" +base_url = "example.com" +extra_watch_paths = ["a", "b"] + "#; + + let config = Config::parse(config_str).unwrap(); + let v = config.extra_watch_paths; + assert_eq!(v, vec!["a", "b"]); + } + #[test] fn link_checker_skip_anchor_prefixes() { let config_str = r#" diff --git a/docs/content/documentation/getting-started/configuration.md b/docs/content/documentation/getting-started/configuration.md index 2565e0913f..d462eff8d7 100644 --- a/docs/content/documentation/getting-started/configuration.md +++ b/docs/content/documentation/getting-started/configuration.md @@ -12,6 +12,7 @@ If you are not familiar with TOML, have a look at [the TOML spec](https://github ⚠️ If you add keys to your `config.toml`, you must pay attention to which TOML section it belongs to. A TOML section starts with a header, e.g. `[search]`, and ends at the next section or EOF. Here are the current `config.toml` sections: + 1. main (unnamed) 2. markdown 3. link_checker @@ -106,6 +107,9 @@ generate_sitemap = true # When set to "false", robots.txt is not generated generate_robots_txt = true +# Extra paths to watch for changes, relative to config.toml +extra_watch_paths = [] + # Configuration of the Markdown rendering [markdown] # When set to "true", all code blocks are highlighted. diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index eb2b75dd26..8fce546c4d 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -462,7 +462,7 @@ 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![ + let mut watch_this = vec![ // The first entry is ultimtely 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 @@ -473,6 +473,12 @@ pub fn serve( ("templates", WatchMode::Optional, RecursiveMode::Recursive), ("themes", WatchMode::Condition(site.config.theme.is_some()), RecursiveMode::Recursive), ]; + watch_this.extend( + site.config + .extra_watch_paths + .iter() + .map(|path| (path.as_str(), WatchMode::Required, RecursiveMode::Recursive)), + ); // Setup watchers let (tx, rx) = channel(); @@ -810,6 +816,12 @@ pub fn serve( site = s; } } + ChangeKind::Unknown => { + // Probably a user-defined watch location. We can't know exactly what to update. + 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 9cd3da8a75..c4e8c699f6 100644 --- a/src/fs_utils.rs +++ b/src/fs_utils.rs @@ -17,6 +17,7 @@ pub enum ChangeKind { StaticFiles, Sass, Config, + Unknown, } /// This enum abstracts over the fine-grained group of enums in `notify`. @@ -156,7 +157,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::Unknown }; (change_kind, partial_path)