From 74fb51ebd34ca5a35dc308ee48c7073603f26bd6 Mon Sep 17 00:00:00 2001 From: Bergmann89 Date: Thu, 13 Oct 2022 15:55:16 +0200 Subject: [PATCH] Ignore files listed in `.mdbookignore` during build --- Cargo.toml | 6 ++-- src/renderer/html_handlebars/hbs_renderer.rs | 19 +++++++++- src/utils/fs.rs | 37 +++++++++++++++----- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 877af7bfb3..1ce783c2ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,11 +20,12 @@ anyhow = "1.0.28" chrono = "0.4" clap = { version = "3.0", features = ["cargo"] } clap_complete = "3.0" -once_cell = "1" env_logger = "0.9.0" +ignore = "0.4" handlebars = "4.0" log = "0.4" memchr = "2.0" +once_cell = "1" opener = "0.5" pulldown-cmark = { version = "0.9.1", default-features = false } regex = "1.5.5" @@ -37,7 +38,6 @@ topological-sort = "0.1.0" # Watch feature notify = { version = "4.0", optional = true } -ignore = { version = "0.4", optional = true } # Serve feature futures-util = { version = "0.3.4", optional = true } @@ -58,7 +58,7 @@ walkdir = "2.0" [features] default = ["watch", "serve", "search"] -watch = ["notify", "ignore"] +watch = ["notify"] serve = ["futures-util", "tokio", "warp"] search = ["elasticlunr-rs", "ammonia"] diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index 710449af0d..47ca002b63 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; use crate::utils::fs::get_404_output_file; use handlebars::Handlebars; +use ignore::gitignore::GitignoreBuilder; use log::{debug, trace, warn}; use once_cell::sync::Lazy; use regex::{Captures, Regex}; @@ -589,7 +590,23 @@ impl Renderer for HtmlHandlebars { .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"])?; + let mut builder = GitignoreBuilder::new(&src_dir); + let mdbook_ignore = src_dir.join(".mdbookignore"); + if mdbook_ignore.exists() { + if let Some(err) = builder.add(mdbook_ignore) { + warn!("Unable to load '.mdbookignore' file: {}", err); + } + } + builder.add_line(None, "*.md")?; + let ignore = builder.build()?; + + utils::fs::copy_files_except_ext( + &src_dir, + destination, + true, + Some(&build_dir), + Some(&ignore), + )?; Ok(()) } diff --git a/src/utils/fs.rs b/src/utils/fs.rs index 0d6f383746..e104f6fc2d 100644 --- a/src/utils/fs.rs +++ b/src/utils/fs.rs @@ -1,4 +1,5 @@ use crate::errors::*; +use ignore::gitignore::Gitignore; use log::{debug, trace}; use std::convert::Into; use std::fs::{self, File}; @@ -94,13 +95,13 @@ pub fn copy_files_except_ext( to: &Path, recursive: bool, avoid_dir: Option<&PathBuf>, - ext_blacklist: &[&str], + ignore: Option<&Gitignore>, ) -> Result<()> { debug!( "Copying all files from {} to {} (blacklist: {:?}), avoiding {:?}", from.display(), to.display(), - ext_blacklist, + ignore, avoid_dir ); @@ -128,6 +129,13 @@ pub fn copy_files_except_ext( } } + if let Some(ignore) = ignore { + let path = entry.path(); + if ignore.matched(&path, path.is_dir()).is_ignore() { + continue; + } + } + // check if output dir already exists if !to.join(entry.file_name()).exists() { fs::create_dir(&to.join(entry.file_name()))?; @@ -138,15 +146,17 @@ pub fn copy_files_except_ext( &to.join(entry.file_name()), true, avoid_dir, - ext_blacklist, + ignore, )?; } else if metadata.is_file() { // Check if it is in the blacklist - if let Some(ext) = entry.path().extension() { - if ext_blacklist.contains(&ext.to_str().unwrap()) { + if let Some(ignore) = ignore { + let path = entry.path(); + if ignore.matched(&path, path.is_dir()).is_ignore() { continue; } } + debug!( "creating path for file: {:?}", &to.join( @@ -191,6 +201,7 @@ pub fn get_404_output_file(input_404: &Option) -> String { #[cfg(test)] mod tests { use super::copy_files_except_ext; + use ignore::gitignore::GitignoreBuilder; use std::{fs, io::Result, path::Path}; #[cfg(target_os = "windows")] @@ -247,9 +258,19 @@ mod tests { panic!("Could not create output/sub_dir_exists: {}", err); } - if let Err(e) = - copy_files_except_ext(tmp.path(), &tmp.path().join("output"), true, None, &["md"]) - { + let ignore = GitignoreBuilder::new(tmp.path()) + .add_line(None, "*.md") + .expect("Unable to add '*.md' to gitignore builder") + .build() + .expect("Unable to build gitignore"); + + if let Err(e) = copy_files_except_ext( + tmp.path(), + &tmp.path().join("output"), + true, + None, + Some(&ignore), + ) { panic!("Error while executing the function:\n{:?}", e); }