Skip to content

Commit

Permalink
Respect the .gitignore and .mdbookignore files
Browse files Browse the repository at this point in the history
  • Loading branch information
Bergmann89 committed Aug 21, 2024
1 parent 256d009 commit a2bdd10
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 16 deletions.
56 changes: 55 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ anyhow = "1.0.47"
env_logger = "0.11.0"
genawaiter = { version = "0.99.1", default-features = false }
html5gum = "0.5.7"
ignore = "0.4"
log = "0.4.0"
mdbook = { version = "0.4.35", default-features = false }
normpath = "1.0.0"
Expand All @@ -33,7 +34,6 @@ serde_yaml = "0.9.0"
tempfile = "3.0.0"
toml = "0.8.0"
ureq = "2.0.0"
walkdir = "2.0.0"

# Increase minimum version requirements of transitive dependencies
thiserror = "1.0.2"
Expand Down
89 changes: 75 additions & 14 deletions src/preprocess.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{

use aho_corasick::AhoCorasick;
use anyhow::{anyhow, Context as _};
use ignore::gitignore::{Gitignore, GitignoreBuilder};
use log::log;
use mdbook::{
book::{BookItems, Chapter},
Expand All @@ -23,9 +24,9 @@ use normpath::PathExt;
use once_cell::sync::Lazy;
use pulldown_cmark::{CodeBlockKind, CowStr, HeadingLevel, LinkType};
use regex::Regex;
use walkdir::WalkDir;

use crate::{
book::Book,
latex,
pandoc::{self, OutputFormat, RenderContext},
};
Expand Down Expand Up @@ -97,19 +98,8 @@ impl<'book> Preprocessor<'book> {
}
fs::create_dir_all(&preprocessed)?;

for entry in WalkDir::new(&ctx.book.source_dir).follow_links(true) {
let entry = entry?;
let src = entry.path();
let dest = preprocessed.join(src.strip_prefix(&ctx.book.source_dir).unwrap());
if entry.file_type().is_dir() {
fs::create_dir_all(&dest)
.with_context(|| format!("Unable to create directory '{}'", dest.display()))?
} else {
fs::copy(src, &dest).with_context(|| {
format!("Unable to copy '{}' -> '{}'", src.display(), dest.display())
})?;
}
}
let ignore = build_ignore(&ctx.book)?;
copy_recursive(&ctx.book.source_dir, &preprocessed, &ignore)?;

let mut chapters = HashMap::new();
for section in ctx.book.book.iter() {
Expand Down Expand Up @@ -1275,6 +1265,77 @@ impl fmt::Debug for IndexedChapter<'_> {
}
}

fn copy_recursive(src: &Path, dst: &Path, ignore: &Gitignore) -> anyhow::Result<()> {
for e in src
.read_dir()
.with_context(|| format!("Unable to read directory {src:#?}"))?
{
let cur = e?.path();

log::info!("Walk: {cur:#?}");

if ignore.matched(&cur, cur.is_dir()).is_ignore() {
log::info!(" Ignore");

continue;
}

if cur.is_dir() {
let dir = dst.join(cur.strip_prefix(&src).unwrap());

fs::create_dir_all(&dir)
.with_context(|| format!("Unable to create directory {dir:#?}"))?;

copy_recursive(&cur, &dir, ignore)?;
} else {
let dst = dst.join(cur.strip_prefix(&src).unwrap());

log::info!(" Copy to: {dst:#?}");

fs::copy(cur, &dst).with_context(|| {
format!("Unable to copy '{}' -> '{}'", src.display(), dst.display())
})?;
}
}

Ok(())
}

fn build_ignore(book: &Book) -> anyhow::Result<Gitignore> {
let root = book.root.canonicalize()?;
let mut src = book.source_dir.canonicalize()?;

let mut builder = GitignoreBuilder::new(&src);

let mdbook_ignore = src.join(".mdbookignore");
if mdbook_ignore.exists() {
if let Some(err) = builder.add(mdbook_ignore) {
log::warn!("Unable to load '.mdbookignore' file: {}", err);
}
}

loop {
let git_ignore = src.join(".gitignore");
if git_ignore.exists() {
if let Some(err) = builder.add(git_ignore) {
log::warn!("Unable to load '.gitignore' file: {}", err);
}
}

if src == root {
break;
}

let Some(parent) = src.parent() else {
break;
};

src = parent.canonicalize()?;
}

Ok(builder.build()?)
}

#[cfg(test)]
mod tests {
use super::Preprocessor;
Expand Down

0 comments on commit a2bdd10

Please sign in to comment.