Ignore files listed in `.mdbookignore` during build

This commit is contained in:
Bergmann89 2022-10-13 15:55:16 +02:00
parent 5a35144d4f
commit 1799d4075e
3 changed files with 49 additions and 11 deletions

View File

@ -39,7 +39,7 @@ topological-sort = "0.2.2"
# Watch feature # Watch feature
notify = { version = "6.1.1", optional = true } notify = { version = "6.1.1", optional = true }
notify-debouncer-mini = { version = "0.4.1", optional = true } notify-debouncer-mini = { version = "0.4.1", optional = true }
ignore = { version = "0.4.20", optional = true } ignore = { version = "0.4.20" }
pathdiff = { version = "0.2.1", optional = true } pathdiff = { version = "0.2.1", optional = true }
# Serve feature # Serve feature
@ -61,7 +61,7 @@ walkdir = "2.3.3"
[features] [features]
default = ["watch", "serve", "search"] default = ["watch", "serve", "search"]
watch = ["dep:notify", "dep:notify-debouncer-mini", "dep:ignore", "dep:pathdiff"] watch = ["dep:notify", "dep:notify-debouncer-mini", "dep:pathdiff"]
serve = ["dep:futures-util", "dep:tokio", "dep:warp"] serve = ["dep:futures-util", "dep:tokio", "dep:warp"]
search = ["dep:elasticlunr-rs", "dep:ammonia"] search = ["dep:elasticlunr-rs", "dep:ammonia"]

View File

@ -14,6 +14,7 @@ use std::path::{Path, PathBuf};
use crate::utils::fs::get_404_output_file; use crate::utils::fs::get_404_output_file;
use handlebars::Handlebars; use handlebars::Handlebars;
use ignore::gitignore::GitignoreBuilder;
use log::{debug, trace, warn}; use log::{debug, trace, warn};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::{Captures, Regex}; use regex::{Captures, Regex};
@ -602,7 +603,23 @@ impl Renderer for HtmlHandlebars {
.context("Unable to emit redirects")?; .context("Unable to emit redirects")?;
// Copy all remaining files, avoid a recursive copy from/to the book build dir // 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(()) Ok(())
} }

View File

@ -1,4 +1,5 @@
use crate::errors::*; use crate::errors::*;
use ignore::gitignore::Gitignore;
use log::{debug, trace}; use log::{debug, trace};
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::Write; use std::io::Write;
@ -92,13 +93,13 @@ pub fn copy_files_except_ext(
to: &Path, to: &Path,
recursive: bool, recursive: bool,
avoid_dir: Option<&PathBuf>, avoid_dir: Option<&PathBuf>,
ext_blacklist: &[&str], ignore: Option<&Gitignore>,
) -> Result<()> { ) -> Result<()> {
debug!( debug!(
"Copying all files from {} to {} (blacklist: {:?}), avoiding {:?}", "Copying all files from {} to {} (blacklist: {:?}), avoiding {:?}",
from.display(), from.display(),
to.display(), to.display(),
ext_blacklist, ignore,
avoid_dir avoid_dir
); );
@ -126,6 +127,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 // check if output dir already exists
if !to.join(entry.file_name()).exists() { if !to.join(entry.file_name()).exists() {
fs::create_dir(&to.join(entry.file_name()))?; fs::create_dir(&to.join(entry.file_name()))?;
@ -136,15 +144,17 @@ pub fn copy_files_except_ext(
&to.join(entry.file_name()), &to.join(entry.file_name()),
true, true,
avoid_dir, avoid_dir,
ext_blacklist, ignore,
)?; )?;
} else if metadata.is_file() { } else if metadata.is_file() {
// Check if it is in the blacklist // Check if it is in the blacklist
if let Some(ext) = entry.path().extension() { if let Some(ignore) = ignore {
if ext_blacklist.contains(&ext.to_str().unwrap()) { let path = entry.path();
if ignore.matched(&path, path.is_dir()).is_ignore() {
continue; continue;
} }
} }
debug!( debug!(
"creating path for file: {:?}", "creating path for file: {:?}",
&to.join( &to.join(
@ -245,6 +255,7 @@ pub fn get_404_output_file(input_404: &Option<String>) -> String {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::copy_files_except_ext; use super::copy_files_except_ext;
use ignore::gitignore::GitignoreBuilder;
use std::{fs, io::Result, path::Path}; use std::{fs, io::Result, path::Path};
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -298,9 +309,19 @@ mod tests {
panic!("Could not create output/sub_dir_exists: {}", err); panic!("Could not create output/sub_dir_exists: {}", err);
} }
if let Err(e) = let ignore = GitignoreBuilder::new(tmp.path())
copy_files_except_ext(tmp.path(), &tmp.path().join("output"), true, None, &["md"]) .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); panic!("Error while executing the function:\n{:?}", e);
} }