From 64ec7e15782bf5fc4f6daa0797c29847b80368c8 Mon Sep 17 00:00:00 2001 From: Johan Sigfrids Date: Sat, 4 Aug 2018 22:47:45 +0300 Subject: [PATCH 1/3] Fix path handling on windows. Delay turning paths into string. Instead, use methods on Path/PathBuf to manipulate paths. This way the Rust Path implementation gets to deal with all werid cross-platform issues. This should fix #359 --- src/cmd/serve.rs | 59 +++++++++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 68fd1a3..f813241 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -219,7 +219,7 @@ pub fn serve(interface: &str, port: &str, output_dir: &str, base_url: &str, conf ws_server.listen(&*ws_address).unwrap(); }); - let pwd = format!("{}", env::current_dir().unwrap().display()); + let pwd = env::current_dir().unwrap(); let mut watchers = vec!["content", "templates", "config.toml"]; if watching_static { @@ -229,7 +229,7 @@ pub fn serve(interface: &str, port: &str, output_dir: &str, base_url: &str, conf watchers.push("sass"); } - println!("Listening for changes in {}/{{{}}}", pwd, watchers.join(", ")); + println!("Listening for changes in {}/{{{}}}", pwd.display(), watchers.join(", ")); println!("Press Ctrl+C to stop\n"); // Delete the output folder on ctrl+C @@ -268,12 +268,12 @@ pub fn serve(interface: &str, port: &str, output_dir: &str, base_url: &str, conf (ChangeKind::StaticFiles, p) => { if path.is_file() { console::info(&format!("-> Static file changes detected {}", path.display())); - rebuild_done_handling(&broadcaster, copy_file(&path, &site.output_path, &site.static_path), &p); + rebuild_done_handling(&broadcaster, copy_file(&path, &site.output_path, &site.static_path), &p.to_string_lossy()); } }, (ChangeKind::Sass, p) => { console::info(&format!("-> Sass file changed {}", path.display())); - rebuild_done_handling(&broadcaster, site.compile_sass(&site.base_path), &p); + rebuild_done_handling(&broadcaster, site.compile_sass(&site.base_path), &p.to_string_lossy()); }, (ChangeKind::Config, _) => { console::info(&format!("-> Config changed. The whole site will be reloaded. The browser needs to be refreshed to make the changes visible.")); @@ -320,31 +320,30 @@ 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: &str, path: &Path) -> (ChangeKind, String) { - let path_str = format!("{}", path.display()) - .replace(pwd, "") - .replace("\\", ""); +fn detect_change_kind(pwd: &Path, path: &Path) -> (ChangeKind, PathBuf) { + let mut partial_path = PathBuf::from("/"); + partial_path.push(path.strip_prefix(pwd).unwrap()); - let change_kind = if path_str.starts_with("/templates") { + let change_kind = if partial_path.starts_with("/templates") { ChangeKind::Templates - } else if path_str.starts_with("/content") { + } else if partial_path.starts_with("/content") { ChangeKind::Content - } else if path_str.starts_with("/static") { + } else if partial_path.starts_with("/static") { ChangeKind::StaticFiles - } else if path_str.starts_with("/sass") { + } else if partial_path.starts_with("/sass") { ChangeKind::Sass - } else if path_str == "/config.toml" { + } else if partial_path == Path::new("/config.toml") { ChangeKind::Config } else { - unreachable!("Got a change in an unexpected path: {}", path_str) + unreachable!("Got a change in an unexpected path: {}", partial_path.display()); }; - (change_kind, path_str) + (change_kind, partial_path) } #[cfg(test)] mod tests { - use std::path::Path; + use std::path::{Path, PathBuf}; use super::{is_temp_file, detect_change_kind, ChangeKind}; @@ -371,24 +370,24 @@ mod tests { fn can_detect_kind_of_changes() { let test_cases = vec![ ( - (ChangeKind::Templates, "/templates/hello.html".to_string()), - "/home/vincent/site", Path::new("/home/vincent/site/templates/hello.html") + (ChangeKind::Templates, PathBuf::from("/templates/hello.html")), + Path::new("/home/vincent/site"), Path::new("/home/vincent/site/templates/hello.html") ), ( - (ChangeKind::StaticFiles, "/static/site.css".to_string()), - "/home/vincent/site", Path::new("/home/vincent/site/static/site.css") + (ChangeKind::StaticFiles, PathBuf::from("/static/site.css")), + Path::new("/home/vincent/site"), Path::new("/home/vincent/site/static/site.css") ), ( - (ChangeKind::Content, "/content/posts/hello.md".to_string()), - "/home/vincent/site", Path::new("/home/vincent/site/content/posts/hello.md") + (ChangeKind::Content, PathBuf::from("/content/posts/hello.md")), + Path::new("/home/vincent/site"), Path::new("/home/vincent/site/content/posts/hello.md") ), ( - (ChangeKind::Sass, "/sass/print.scss".to_string()), - "/home/vincent/site", Path::new("/home/vincent/site/sass/print.scss") + (ChangeKind::Sass, PathBuf::from("/sass/print.scss")), + Path::new("/home/vincent/site"), Path::new("/home/vincent/site/sass/print.scss") ), ( - (ChangeKind::Config, "/config.toml".to_string()), - "/home/vincent/site", 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") ), ]; @@ -398,4 +397,12 @@ mod tests { } + #[test] + fn windows_path_handling() { + 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"#); + assert_eq!(expected, detect_change_kind(pwd, path)); + } + } From 9be5e640ffc8ed44cf892aaa0a7ebb589be6abf5 Mon Sep 17 00:00:00 2001 From: Johan Sigfrids Date: Sat, 4 Aug 2018 23:28:39 +0300 Subject: [PATCH 2/3] Only test windows path handling on windows. Otherwise Path won't know what to do. --- src/cmd/serve.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index f813241..3cf5f97 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -398,6 +398,7 @@ mod tests { #[test] + #[cfg(windows)] fn windows_path_handling() { let expected = (ChangeKind::Templates, PathBuf::from("/templates/hello.html")); let pwd = Path::new(r#"C:\\Users\johan\site"#); From 883357a7ddeafb7ac1dd31312de0e85b55a3dd66 Mon Sep 17 00:00:00 2001 From: Johan Sigfrids Date: Sun, 5 Aug 2018 08:59:56 +0300 Subject: [PATCH 3/3] Handle relative path case --- src/cmd/serve.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 3cf5f97..2406de0 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -322,7 +322,7 @@ fn is_temp_file(path: &Path) -> bool { /// to be reloaded fn detect_change_kind(pwd: &Path, path: &Path) -> (ChangeKind, PathBuf) { let mut partial_path = PathBuf::from("/"); - partial_path.push(path.strip_prefix(pwd).unwrap()); + partial_path.push(path.strip_prefix(pwd).unwrap_or(path)); let change_kind = if partial_path.starts_with("/templates") { ChangeKind::Templates @@ -396,7 +396,6 @@ mod tests { } } - #[test] #[cfg(windows)] fn windows_path_handling() { @@ -406,4 +405,11 @@ mod tests { assert_eq!(expected, detect_change_kind(pwd, path)); } + #[test] + fn relative_path() { + let expected = (ChangeKind::Templates, PathBuf::from("/templates/hello.html")); + let pwd = Path::new("/home/johan/site"); + let path = Path::new("templates/hello.html"); + assert_eq!(expected, detect_change_kind(pwd, path)); + } }