From da55cf273f8f054a5837ba2804dd70976ea6a3a0 Mon Sep 17 00:00:00 2001 From: Michael-F-Bryan Date: Wed, 27 May 2020 03:12:57 +0800 Subject: [PATCH] Changed redirect mapping to HashMap and improved error handling --- src/config.rs | 6 ++-- src/renderer/html_handlebars/hbs_renderer.rs | 33 +++++++++++++++++--- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 71edbaf2..dc712bbb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -517,7 +517,7 @@ pub struct HtmlConfig { pub livereload_url: Option, /// The mapping from old pages to new pages/URLs to use when generating /// redirects. - pub redirect: HashMap, + pub redirect: HashMap, } impl Default for HtmlConfig { @@ -741,9 +741,9 @@ mod tests { git_repository_url: Some(String::from("https://foo.com/")), git_repository_icon: Some(String::from("fa-code-fork")), redirect: vec![ - (PathBuf::from("index.html"), String::from("overview.html")), + (String::from("index.html"), String::from("overview.html")), ( - PathBuf::from("nexted/page.md"), + String::from("nexted/page.md"), String::from("https://rust-lang.org/"), ), ] diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 2953f098..ecb8359e 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -284,7 +284,7 @@ impl HtmlHandlebars { &self, root: &Path, handlebars: &Handlebars<'_>, - redirects: &HashMap, + redirects: &HashMap, ) -> Result<()> { if redirects.is_empty() { return Ok(()); @@ -293,7 +293,11 @@ impl HtmlHandlebars { log::debug!("Emitting redirects"); for (original, new) in redirects { - log::debug!("Redirecting \"{}\" → \"{}\"", original.display(), new); + log::debug!("Redirecting \"{}\" → \"{}\"", original, new); + // Note: all paths are relative to the build directory, so the + // leading slash in an absolute path means nothing (and would mess + // up `root.join(original)`). + let original = original.trim_start_matches("/"); let filename = root.join(original); self.emit_redirect(handlebars, &filename, new)?; } @@ -307,15 +311,33 @@ impl HtmlHandlebars { original: &Path, destination: &str, ) -> Result<()> { + if original.exists() { + // sanity check to avoid accidentally overwriting a real file. + let msg = format!( + "Not redirecting \"{}\" to \"{}\" because it already exists. Are you sure it needs to be redirected?", + original.display(), + destination, + ); + return Err(Error::msg(msg)); + } + if let Some(parent) = original.parent() { - std::fs::create_dir_all(parent)?; + std::fs::create_dir_all(parent) + .with_context(|| format!("Unable to ensure \"{}\" exists", parent.display()))?; } let ctx = json!({ "url": destination, }); let f = File::create(original)?; - handlebars.render_to_write("redirect", &ctx, f)?; + handlebars + .render_to_write("redirect", &ctx, f) + .with_context(|| { + format!( + "Unable to create a redirect file at \"{}\"", + original.display() + ) + })?; Ok(()) } @@ -445,7 +467,8 @@ impl Renderer for HtmlHandlebars { } } - self.emit_redirects(&ctx.destination, &handlebars, &html_config.redirect)?; + self.emit_redirects(&ctx.destination, &handlebars, &html_config.redirect) + .context("Unable to emit redirects")?; // Copy all remaining files, avoid a recursive copy from/to the book build dir utils::fs::copy_files_except_ext(&src_dir, &destination, true, Some(&build_dir), &["md"])?;