@@ -4,6 +4,7 @@ use ignore::gitignore::Gitignore;
4
4
use mdbook:: errors:: Result ;
5
5
use mdbook:: utils;
6
6
use mdbook:: MDBook ;
7
+ use pathdiff:: diff_paths;
7
8
use std:: path:: { Path , PathBuf } ;
8
9
use std:: sync:: mpsc:: channel;
9
10
use std:: thread:: sleep;
@@ -86,12 +87,21 @@ fn find_gitignore(book_root: &Path) -> Option<PathBuf> {
86
87
. find ( |p| p. exists ( ) )
87
88
}
88
89
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).
89
92
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
+
90
98
paths
91
99
. iter ( )
92
100
. filter ( |path| {
101
+ let relative_path =
102
+ diff_paths ( & path, & ignore_root) . expect ( "One of the paths should be an absolute" ) ;
93
103
!ignore
94
- . matched_path_or_any_parents ( path , path . is_dir ( ) )
104
+ . matched_path_or_any_parents ( & relative_path , relative_path . is_dir ( ) )
95
105
. is_ignore ( )
96
106
} )
97
107
. map ( |path| path. to_path_buf ( ) )
@@ -176,3 +186,44 @@ where
176
186
}
177
187
}
178
188
}
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