1
1
//! Access common paths and manipulate the filesystem
2
2
3
3
use filetime:: FileTime ;
4
+ use itertools:: Itertools ;
5
+ use walkdir:: WalkDir ;
4
6
5
7
use std:: cell:: RefCell ;
6
8
use std:: env;
@@ -12,6 +14,9 @@ use std::sync::Mutex;
12
14
use std:: sync:: OnceLock ;
13
15
use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
14
16
17
+ use crate :: compare:: assert_e2e;
18
+ use crate :: compare:: match_contains;
19
+
15
20
static CARGO_INTEGRATION_TEST_DIR : & str = "cit" ;
16
21
17
22
static GLOBAL_ROOT : OnceLock < Mutex < Option < PathBuf > > > = OnceLock :: new ( ) ;
@@ -152,6 +157,14 @@ pub trait CargoPathExt {
152
157
fn move_in_time < F > ( & self , travel_amount : F )
153
158
where
154
159
F : Fn ( i64 , u32 ) -> ( i64 , u32 ) ;
160
+
161
+ fn assert_file_layout ( & self , expected : impl snapbox:: IntoData ) ;
162
+
163
+ fn assert_file_layout_with_ignored_paths (
164
+ & self ,
165
+ expected : impl snapbox:: IntoData ,
166
+ ignored : & [ PathBuf ] ,
167
+ ) ;
155
168
}
156
169
157
170
impl CargoPathExt for Path {
@@ -236,6 +249,37 @@ impl CargoPathExt for Path {
236
249
} ) ;
237
250
}
238
251
}
252
+
253
+ #[ track_caller]
254
+ fn assert_file_layout ( & self , expected : impl snapbox:: IntoData ) {
255
+ self . assert_file_layout_with_ignored_paths ( expected, & default_ignored_paths ( ) ) ;
256
+ }
257
+
258
+ #[ track_caller]
259
+ fn assert_file_layout_with_ignored_paths (
260
+ & self ,
261
+ expected : impl snapbox:: IntoData ,
262
+ ignored_paths : & [ PathBuf ] ,
263
+ ) {
264
+ let assert = assert_e2e ( ) ;
265
+ let actual = WalkDir :: new ( self )
266
+ . into_iter ( )
267
+ . filter_map ( |e| e. ok ( ) )
268
+ . filter ( |e| e. file_type ( ) . is_file ( ) )
269
+ . map ( |e| e. path ( ) . to_string_lossy ( ) . into_owned ( ) )
270
+ . filter ( |file| {
271
+ for ignored in ignored_paths {
272
+ let ignored = ignored. to_str ( ) . unwrap ( ) ;
273
+ if match_contains ( & ignored, file, & assert. redactions ( ) ) . is_ok ( ) {
274
+ return false ;
275
+ }
276
+ }
277
+ return true ;
278
+ } )
279
+ . join ( "\n " ) ;
280
+
281
+ assert. eq ( format ! ( "{actual}\n " ) , expected. unordered ( ) ) ;
282
+ }
239
283
}
240
284
241
285
impl CargoPathExt for PathBuf {
@@ -260,6 +304,21 @@ impl CargoPathExt for PathBuf {
260
304
{
261
305
self . as_path ( ) . move_in_time ( travel_amount)
262
306
}
307
+
308
+ #[ track_caller]
309
+ fn assert_file_layout ( & self , expected : impl snapbox:: IntoData ) {
310
+ self . as_path ( ) . assert_file_layout ( expected) ;
311
+ }
312
+
313
+ #[ track_caller]
314
+ fn assert_file_layout_with_ignored_paths (
315
+ & self ,
316
+ expected : impl snapbox:: IntoData ,
317
+ ignored_paths : & [ PathBuf ] ,
318
+ ) {
319
+ self . as_path ( )
320
+ . assert_file_layout_with_ignored_paths ( expected, ignored_paths) ;
321
+ }
263
322
}
264
323
265
324
fn do_op < F > ( path : & Path , desc : & str , mut f : F )
@@ -290,6 +349,20 @@ where
290
349
}
291
350
}
292
351
352
+ /// The default paths to ignore when [`CargoPathExt::assert_file_layout`] is called
353
+ fn default_ignored_paths ( ) -> Vec < PathBuf > {
354
+ vec ! [
355
+ // Ignore MacOS debug symbols as there are many files/directories that would clutter up
356
+ // tests few not a lot of benefit.
357
+ "[..].dSYM/[..]" ,
358
+ // Ignore Windows debub symbols files (.pdb)
359
+ "[..].pdb" ,
360
+ ]
361
+ . into_iter ( )
362
+ . map ( |s| PathBuf :: from ( s) )
363
+ . collect ( )
364
+ }
365
+
293
366
/// Get the filename for a library.
294
367
///
295
368
/// `kind` should be one of:
0 commit comments