diff --git a/src/command/build/render.rs b/src/command/build/render.rs index 7ec4410..a5420cb 100644 --- a/src/command/build/render.rs +++ b/src/command/build/render.rs @@ -93,15 +93,20 @@ impl SiteRenderer { self.output_directory.as_path(), output_path.as_path(), None, - dependency_manager, + dependency_manager.clone(), )?; - let render_context = RenderPage::new(render_context, page)?; - let rendered_output = renderer_integration.render(render_context)?; + let dust_context = RenderPage::new(render_context.clone(), page)?; + let rendered_output = renderer_integration.render(dust_context)?; let parent_directory = output_path .parent() .ok_or("Output file should have a containing directory.")?; tokio::fs::create_dir_all(parent_directory).await?; - tokio::fs::write(output_path, rendered_output).await?; + tokio::fs::write(&output_path, rendered_output).await?; + + let dependencies = dependency_manager.lock().unwrap().take_dependencies(); + for dependency in dependencies { + dependency.perform(render_context.clone()).await?; + } } Ok(()) @@ -125,18 +130,20 @@ impl SiteRenderer { self.output_directory.as_path(), output_path.as_path(), None, - dependency_manager, + dependency_manager.clone(), )?; - let render_context = RenderBlogPostPage::new(render_context, &convert_input)?; - let rendered_output = renderer_integration.render(render_context)?; + let dust_context = RenderBlogPostPage::new(render_context.clone(), &convert_input)?; + let rendered_output = renderer_integration.render(dust_context)?; let parent_directory = output_path .parent() .ok_or("Output file should have a containing directory.")?; tokio::fs::create_dir_all(parent_directory).await?; - tokio::fs::write(output_path, rendered_output).await?; + tokio::fs::write(&output_path, rendered_output).await?; - // TODO: Copy post files to output. - // TODO: Update link src to generate path correct for where the page is rendered. + let dependencies = dependency_manager.lock().unwrap().take_dependencies(); + for dependency in dependencies { + dependency.perform(render_context.clone()).await?; + } } } @@ -212,9 +219,9 @@ impl SiteRenderer { self.output_directory.as_path(), output_file.as_path(), None, - dependency_manager, + dependency_manager.clone(), )?; - let blog_stream = RenderBlogStream::new(render_context, &convert_input)?; + let blog_stream = RenderBlogStream::new(render_context.clone(), &convert_input)?; // Pass each RenderBlogStream to dust as the context to render index.html and any additional stream pages. let rendered_output = renderer_integration.render(blog_stream)?; @@ -222,7 +229,12 @@ impl SiteRenderer { .parent() .ok_or("Output file should have a containing directory.")?; tokio::fs::create_dir_all(parent_directory).await?; - tokio::fs::write(output_file, rendered_output).await?; + tokio::fs::write(&output_file, rendered_output).await?; + + let dependencies = dependency_manager.lock().unwrap().take_dependencies(); + for dependency in dependencies { + dependency.perform(render_context.clone()).await?; + } } Ok(()) } diff --git a/src/context/dependency.rs b/src/context/dependency.rs new file mode 100644 index 0000000..aa4aab7 --- /dev/null +++ b/src/context/dependency.rs @@ -0,0 +1,36 @@ +use std::path::PathBuf; + +use crate::error::CustomError; + +use super::RenderContext; + +#[derive(Debug)] +pub(crate) enum Dependency { + StaticFile { absolute_path: PathBuf }, +} + +impl Dependency { + pub(crate) async fn perform( + &self, + render_context: RenderContext<'_>, + ) -> Result<(), CustomError> { + match self { + Dependency::StaticFile { absolute_path } => { + let input_root_directory = render_context.config.get_root_directory(); + let relative_path_to_file = absolute_path.strip_prefix(input_root_directory)?; + let path_to_output = render_context + .output_root_directory + .join(relative_path_to_file); + tokio::fs::create_dir_all( + path_to_output + .parent() + .ok_or("Output file should have a containing directory.")?, + ) + .await?; + // TODO: If file already exists, either error out or compare hash to avoid duplicate write. + tokio::fs::copy(absolute_path, path_to_output).await?; + Ok(()) + } + } + } +} diff --git a/src/context/dependency_manager.rs b/src/context/dependency_manager.rs index 0147a7b..a5355b6 100644 --- a/src/context/dependency_manager.rs +++ b/src/context/dependency_manager.rs @@ -58,4 +58,11 @@ impl DependencyManager { }); Ok(()) } + + /// Return the dependencies and forget about them. + pub(crate) fn take_dependencies(&mut self) -> Vec { + let mut dependencies = Vec::new(); + std::mem::swap(&mut self.dependencies, &mut dependencies); + dependencies + } }