diff --git a/Cargo.lock b/Cargo.lock index 7615a68f..96a1c806 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3438,6 +3438,7 @@ dependencies = [ "mime_guess", "notify", "open", + "pathdiff", "percent-encoding", "relative-path", "same-file", diff --git a/Cargo.toml b/Cargo.toml index a737e008..8175ddda 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,6 +36,7 @@ ctrlc = "3" open = "2" globset = "0.4" relative-path = "1" +pathdiff = "0.2" serde_json = "1.0" # For mimetype detection in serve mode mime_guess = "2.0" diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 8591615f..f08f57fe 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -40,6 +40,7 @@ use ws::{Message, Sender, WebSocket}; use errors::{Error as ZolaError, Result}; use globset::GlobSet; +use pathdiff::diff_paths; use relative_path::{RelativePath, RelativePathBuf}; use site::sass::compile_sass; use site::{Site, SITE_CONTENT}; @@ -300,12 +301,14 @@ pub fn serve( return Err(format!("Cannot start server on address {}.", address).into()); } - let config_path = config_file.to_str().unwrap_or("config.toml"); + let config_path = PathBuf::from(config_file); + let config_path_rel = diff_paths(&config_path, &root_dir).unwrap_or(config_path.clone()); - // An array of (path, bool, bool) where the path should be watched for changes, and the boolean value - // indicates whether this file/folder must exist for zola serve to operate + // An array of (path, WatchMode) where the path should be watched for changes, + // and the WatchMode value indicates whether this file/folder must exist for + // zola serve to operate let watch_this = vec![ - (config_path, WatchMode::Required), + (config_path_rel.to_str().unwrap_or("config.toml"), WatchMode::Required), ("content", WatchMode::Required), ("sass", WatchMode::Condition(site.config.compile_sass)), ("static", WatchMode::Optional), @@ -518,7 +521,7 @@ pub fn serve( ); let start = Instant::now(); - match detect_change_kind(root_dir, &path, config_path) { + match detect_change_kind(root_dir, &path, &config_path) { (ChangeKind::Content, _) => { console::info(&format!("-> Content changed {}", path.display())); @@ -644,13 +647,10 @@ fn is_temp_file(path: &Path) -> bool { /// Detect what changed from the given path so we have an idea what needs /// to be reloaded -fn detect_change_kind(pwd: &Path, path: &Path, config_filename: &str) -> (ChangeKind, PathBuf) { +fn detect_change_kind(pwd: &Path, path: &Path, config_path: &Path) -> (ChangeKind, PathBuf) { let mut partial_path = PathBuf::from("/"); partial_path.push(path.strip_prefix(pwd).unwrap_or(path)); - let mut partial_config_path = PathBuf::from("/"); - partial_config_path.push(config_filename); - let change_kind = if partial_path.starts_with("/templates") { ChangeKind::Templates } else if partial_path.starts_with("/themes") { @@ -661,7 +661,7 @@ fn detect_change_kind(pwd: &Path, path: &Path, config_filename: &str) -> (Change ChangeKind::StaticFiles } else if partial_path.starts_with("/sass") { ChangeKind::Sass - } else if partial_path == partial_config_path { + } else if path == config_path { ChangeKind::Config } else { unreachable!("Got a change in an unexpected path: {}", partial_path.display()); @@ -709,43 +709,43 @@ mod tests { (ChangeKind::Templates, PathBuf::from("/templates/hello.html")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/templates/hello.html"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::Themes, PathBuf::from("/themes/hello.html")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/themes/hello.html"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::StaticFiles, PathBuf::from("/static/site.css")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/static/site.css"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::Content, PathBuf::from("/content/posts/hello.md")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/content/posts/hello.md"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::Sass, PathBuf::from("/sass/print.scss")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/sass/print.scss"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::Config, PathBuf::from("/config.toml")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/config.toml"), - "config.toml", + Path::new("/home/vincent/site/config.toml"), ), ( (ChangeKind::Config, PathBuf::from("/config.staging.toml")), Path::new("/home/vincent/site"), Path::new("/home/vincent/site/config.staging.toml"), - "config.staging.toml", + Path::new("/home/vincent/site/config.staging.toml"), ), ]; @@ -760,7 +760,7 @@ mod tests { let expected = (ChangeKind::Templates, PathBuf::from("/templates/hello.html")); let pwd = Path::new(r#"C:\\Users\johan\site"#); let path = Path::new(r#"C:\\Users\johan\site\templates\hello.html"#); - let config_filename = "config.toml"; + let config_filename = Path::new(r#"C:\\Users\johan\site\config.toml"#); assert_eq!(expected, detect_change_kind(pwd, path, config_filename)); } @@ -769,7 +769,7 @@ mod tests { let expected = (ChangeKind::Templates, PathBuf::from("/templates/hello.html")); let pwd = Path::new("/home/johan/site"); let path = Path::new("templates/hello.html"); - let config_filename = "config.toml"; + let config_filename = Path::new("config.toml"); assert_eq!(expected, detect_change_kind(pwd, path, config_filename)); } } diff --git a/src/main.rs b/src/main.rs index 925d36d3..00991967 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,9 @@ fn main() { .unwrap_or_else(|_| panic!("Cannot find root directory: {}", path)), }; let config_file = match matches.value_of("config") { - Some(path) => PathBuf::from(path), + Some(path) => PathBuf::from(path) + .canonicalize() + .unwrap_or_else(|_| panic!("Cannot find config file: {}", path)), None => root_dir.join("config.toml"), };