Skip to content

Commit 8d4193f

Browse files
authored
Merge pull request #2229 from leonzchang/fix/normalize-path
Fix `mdbook serve` unexpected panic
2 parents 208d5ea + 8d4ae38 commit 8d4193f

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ log = "0.4.17"
2828
memchr = "2.5.0"
2929
opener = "0.6.1"
3030
pulldown-cmark = { version = "0.9.3", default-features = false }
31+
pathdiff = "0.2.1"
3132
regex = "1.8.1"
3233
serde = { version = "1.0.163", features = ["derive"] }
3334
serde_json = "1.0.96"

src/cmd/watch.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use ignore::gitignore::Gitignore;
44
use mdbook::errors::Result;
55
use mdbook::utils;
66
use mdbook::MDBook;
7+
use pathdiff::diff_paths;
78
use std::path::{Path, PathBuf};
89
use std::sync::mpsc::channel;
910
use std::thread::sleep;
@@ -86,12 +87,21 @@ fn find_gitignore(book_root: &Path) -> Option<PathBuf> {
8687
.find(|p| p.exists())
8788
}
8889

90+
// Note: The usage of `canonicalize` may encounter occasional failures on the Windows platform, presenting a potential risk.
91+
// For more details, refer to [Pull Request #2229](https://github.com/rust-lang/mdBook/pull/2229#discussion_r1408665981).
8992
fn filter_ignored_files(ignore: Gitignore, paths: &[PathBuf]) -> Vec<PathBuf> {
93+
let ignore_root = ignore
94+
.path()
95+
.canonicalize()
96+
.expect("ignore root canonicalize error");
97+
9098
paths
9199
.iter()
92100
.filter(|path| {
101+
let relative_path =
102+
diff_paths(&path, &ignore_root).expect("One of the paths should be an absolute");
93103
!ignore
94-
.matched_path_or_any_parents(path, path.is_dir())
104+
.matched_path_or_any_parents(&relative_path, relative_path.is_dir())
95105
.is_ignore()
96106
})
97107
.map(|path| path.to_path_buf())
@@ -176,3 +186,44 @@ where
176186
}
177187
}
178188
}
189+
190+
#[cfg(test)]
191+
mod tests {
192+
use super::*;
193+
use ignore::gitignore::GitignoreBuilder;
194+
use std::env;
195+
196+
#[test]
197+
fn test_filter_ignored_files() {
198+
let current_dir = env::current_dir().unwrap();
199+
200+
let ignore = GitignoreBuilder::new(&current_dir)
201+
.add_line(None, "*.html")
202+
.unwrap()
203+
.build()
204+
.unwrap();
205+
let should_remain = current_dir.join("record.text");
206+
let should_filter = current_dir.join("index.html");
207+
208+
let remain = filter_ignored_files(ignore, &[should_remain.clone(), should_filter]);
209+
assert_eq!(remain, vec![should_remain])
210+
}
211+
212+
#[test]
213+
fn filter_ignored_files_should_handle_parent_dir() {
214+
let current_dir = env::current_dir().unwrap();
215+
216+
let ignore = GitignoreBuilder::new(&current_dir)
217+
.add_line(None, "*.html")
218+
.unwrap()
219+
.build()
220+
.unwrap();
221+
222+
let parent_dir = current_dir.join("..");
223+
let should_remain = parent_dir.join("record.text");
224+
let should_filter = parent_dir.join("index.html");
225+
226+
let remain = filter_ignored_files(ignore, &[should_remain.clone(), should_filter]);
227+
assert_eq!(remain, vec![should_remain])
228+
}
229+
}

0 commit comments

Comments
 (0)