diff --git a/src/command/build/render.rs b/src/command/build/render.rs index 642a386..d17b188 100644 --- a/src/command/build/render.rs +++ b/src/command/build/render.rs @@ -1,8 +1,11 @@ use std::ffi::OsStr; +use std::path::Path; use std::path::PathBuf; use include_dir::include_dir; use include_dir::Dir; +use tokio::task::JoinHandle; +use walkdir::WalkDir; use crate::config::Config; use crate::context::RenderBlogPostPage; @@ -196,6 +199,27 @@ impl SiteRenderer { } Ok(()) } + + pub(crate) async fn copy_static_files(&self, config: &Config) -> Result<(), CustomError> { + let static_files_directory = config + .get_root_directory() + .join(config.get_relative_path_to_static_files()); + if !static_files_directory.exists() { + return Ok(()); + } + let static_files = get_all_files(&static_files_directory)?; + for entry in static_files { + let (path, contents) = entry.await??; + let relative_path = path.strip_prefix(&static_files_directory)?; + let output_path = self.output_directory.join(relative_path); + 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, contents).await?; + } + Ok(()) + } } fn build_name_contents_pairs<'a>( @@ -210,3 +234,25 @@ fn build_name_contents_pairs<'a>( let contents = std::str::from_utf8(entry.contents())?; Ok((name, contents)) } + +fn get_all_files>( + root_dir: P, +) -> Result)>>>, walkdir::Error> { + let files = WalkDir::new(root_dir) + .into_iter() + .filter(|e| match e { + Ok(dir_entry) => dir_entry.file_type().is_file(), + Err(_) => true, + }) + .collect::, _>>()?; + let org_files = files + .into_iter() + .map(walkdir::DirEntry::into_path) + .map(|path| tokio::spawn(read_file(path))); + Ok(org_files) +} + +async fn read_file(path: PathBuf) -> std::io::Result<(PathBuf, Vec)> { + let contents = tokio::fs::read(&path).await?; + Ok((path, contents)) +} diff --git a/src/command/build/runner.rs b/src/command/build/runner.rs index bd3e931..391d0a1 100644 --- a/src/command/build/runner.rs +++ b/src/command/build/runner.rs @@ -25,6 +25,7 @@ pub(crate) async fn build_site(args: BuildArgs) -> Result<(), CustomError> { renderer.render_blog_posts(&config).await?; renderer.render_blog_stream(&config).await?; renderer.render_stylesheets().await?; + renderer.copy_static_files(&config).await?; Ok(()) } diff --git a/src/config/full.rs b/src/config/full.rs index 3c9717f..5c7d3af 100644 --- a/src/config/full.rs +++ b/src/config/full.rs @@ -88,4 +88,8 @@ impl Config { .and_then(|stream| stream.entries_per_page) .unwrap_or(5) } + + pub(crate) fn get_relative_path_to_static_files(&self) -> PathBuf { + Path::new("static").into() + } }