Skip to content

Commit adbf35f

Browse files
committed
Respect the .gitignore and .mdbookignore files
1 parent 256d009 commit adbf35f

File tree

3 files changed

+125
-16
lines changed

3 files changed

+125
-16
lines changed

Cargo.lock

Lines changed: 55 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ anyhow = "1.0.47"
1919
env_logger = "0.11.0"
2020
genawaiter = { version = "0.99.1", default-features = false }
2121
html5gum = "0.5.7"
22+
ignore = "0.4"
2223
log = "0.4.0"
2324
mdbook = { version = "0.4.35", default-features = false }
2425
normpath = "1.0.0"
@@ -33,7 +34,6 @@ serde_yaml = "0.9.0"
3334
tempfile = "3.0.0"
3435
toml = "0.8.0"
3536
ureq = "2.0.0"
36-
walkdir = "2.0.0"
3737

3838
# Increase minimum version requirements of transitive dependencies
3939
thiserror = "1.0.2"

src/preprocess.rs

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::{
1414

1515
use aho_corasick::AhoCorasick;
1616
use anyhow::{anyhow, Context as _};
17+
use ignore::gitignore::{Gitignore, GitignoreBuilder};
1718
use log::log;
1819
use mdbook::{
1920
book::{BookItems, Chapter},
@@ -23,9 +24,9 @@ use normpath::PathExt;
2324
use once_cell::sync::Lazy;
2425
use pulldown_cmark::{CodeBlockKind, CowStr, HeadingLevel, LinkType};
2526
use regex::Regex;
26-
use walkdir::WalkDir;
2727

2828
use crate::{
29+
book::Book,
2930
latex,
3031
pandoc::{self, OutputFormat, RenderContext},
3132
};
@@ -97,19 +98,8 @@ impl<'book> Preprocessor<'book> {
9798
}
9899
fs::create_dir_all(&preprocessed)?;
99100

100-
for entry in WalkDir::new(&ctx.book.source_dir).follow_links(true) {
101-
let entry = entry?;
102-
let src = entry.path();
103-
let dest = preprocessed.join(src.strip_prefix(&ctx.book.source_dir).unwrap());
104-
if entry.file_type().is_dir() {
105-
fs::create_dir_all(&dest)
106-
.with_context(|| format!("Unable to create directory '{}'", dest.display()))?
107-
} else {
108-
fs::copy(src, &dest).with_context(|| {
109-
format!("Unable to copy '{}' -> '{}'", src.display(), dest.display())
110-
})?;
111-
}
112-
}
101+
let ignore = build_ignore(&ctx.book)?;
102+
copy_recursive(&ctx.book.source_dir, &preprocessed, &ignore)?;
113103

114104
let mut chapters = HashMap::new();
115105
for section in ctx.book.book.iter() {
@@ -1275,6 +1265,71 @@ impl fmt::Debug for IndexedChapter<'_> {
12751265
}
12761266
}
12771267

1268+
fn copy_recursive(src: &Path, dst: &Path, ignore: &Gitignore) -> anyhow::Result<()> {
1269+
for e in src
1270+
.read_dir()
1271+
.with_context(|| format!("Unable to read directory {src:#?}"))?
1272+
{
1273+
let cur = e?.path();
1274+
1275+
if ignore.matched(&cur, cur.is_dir()).is_ignore() {
1276+
continue;
1277+
}
1278+
1279+
if cur.is_dir() {
1280+
let dir = dst.join(cur.strip_prefix(&src).unwrap());
1281+
1282+
fs::create_dir_all(&dir)
1283+
.with_context(|| format!("Unable to create directory {dir:#?}"))?;
1284+
1285+
copy_recursive(&cur, &dir, ignore)?;
1286+
} else {
1287+
let dst = dst.join(cur.strip_prefix(&src).unwrap());
1288+
1289+
fs::copy(cur, &dst).with_context(|| {
1290+
format!("Unable to copy '{}' -> '{}'", src.display(), dst.display())
1291+
})?;
1292+
}
1293+
}
1294+
1295+
Ok(())
1296+
}
1297+
1298+
fn build_ignore(book: &Book) -> anyhow::Result<Gitignore> {
1299+
let root = book.root.canonicalize()?;
1300+
let mut src = book.source_dir.canonicalize()?;
1301+
1302+
let mut builder = GitignoreBuilder::new(&src);
1303+
1304+
let mdbook_ignore = src.join(".mdbookignore");
1305+
if mdbook_ignore.exists() {
1306+
if let Some(err) = builder.add(mdbook_ignore) {
1307+
log::warn!("Unable to load '.mdbookignore' file: {}", err);
1308+
}
1309+
}
1310+
1311+
loop {
1312+
let git_ignore = src.join(".gitignore");
1313+
if git_ignore.exists() {
1314+
if let Some(err) = builder.add(git_ignore) {
1315+
log::warn!("Unable to load '.gitignore' file: {}", err);
1316+
}
1317+
}
1318+
1319+
if src == root {
1320+
break;
1321+
}
1322+
1323+
let Some(parent) = src.parent() else {
1324+
break;
1325+
};
1326+
1327+
src = parent.canonicalize()?;
1328+
}
1329+
1330+
Ok(builder.build()?)
1331+
}
1332+
12781333
#[cfg(test)]
12791334
mod tests {
12801335
use super::Preprocessor;

0 commit comments

Comments
 (0)