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,10 @@ 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_build_dir_layout ( & self , expected : impl snapbox:: IntoData ) ;
162
+
163
+ fn assert_dir_layout ( & self , expected : impl snapbox:: IntoData , ignored_path_patterns : & [ String ] ) ;
155
164
}
156
165
157
166
impl CargoPathExt for Path {
@@ -236,6 +245,37 @@ impl CargoPathExt for Path {
236
245
} ) ;
237
246
}
238
247
}
248
+
249
+ #[ track_caller]
250
+ fn assert_build_dir_layout ( & self , expected : impl snapbox:: IntoData ) {
251
+ self . assert_dir_layout ( expected. unordered ( ) , & build_dir_ignored_path_patterns ( ) ) ;
252
+ }
253
+
254
+ #[ track_caller]
255
+ fn assert_dir_layout (
256
+ & self ,
257
+ expected : impl snapbox:: IntoData ,
258
+ ignored_path_patterns : & [ String ] ,
259
+ ) {
260
+ let assert = assert_e2e ( ) ;
261
+ let actual = WalkDir :: new ( self )
262
+ . sort_by_file_name ( )
263
+ . into_iter ( )
264
+ . filter_map ( |e| e. ok ( ) )
265
+ . filter ( |e| e. file_type ( ) . is_file ( ) )
266
+ . map ( |e| e. path ( ) . to_string_lossy ( ) . into_owned ( ) )
267
+ . filter ( |file| {
268
+ for ignored in ignored_path_patterns {
269
+ if match_contains ( & ignored, file, & assert. redactions ( ) ) . is_ok ( ) {
270
+ return false ;
271
+ }
272
+ }
273
+ return true ;
274
+ } )
275
+ . join ( "\n " ) ;
276
+
277
+ assert. eq ( format ! ( "{actual}\n " ) , expected) ;
278
+ }
239
279
}
240
280
241
281
impl CargoPathExt for PathBuf {
@@ -260,6 +300,21 @@ impl CargoPathExt for PathBuf {
260
300
{
261
301
self . as_path ( ) . move_in_time ( travel_amount)
262
302
}
303
+
304
+ #[ track_caller]
305
+ fn assert_build_dir_layout ( & self , expected : impl snapbox:: IntoData ) {
306
+ self . as_path ( ) . assert_build_dir_layout ( expected) ;
307
+ }
308
+
309
+ #[ track_caller]
310
+ fn assert_dir_layout (
311
+ & self ,
312
+ expected : impl snapbox:: IntoData ,
313
+ ignored_path_patterns : & [ String ] ,
314
+ ) {
315
+ self . as_path ( )
316
+ . assert_dir_layout ( expected, ignored_path_patterns) ;
317
+ }
263
318
}
264
319
265
320
fn do_op < F > ( path : & Path , desc : & str , mut f : F )
@@ -290,6 +345,20 @@ where
290
345
}
291
346
}
292
347
348
+ /// The paths to ignore when [`CargoPathExt::assert_build_dir_layout`] is called
349
+ fn build_dir_ignored_path_patterns ( ) -> Vec < String > {
350
+ vec ! [
351
+ // Ignore MacOS debug symbols as there are many files/directories that would clutter up
352
+ // tests few not a lot of benefit.
353
+ "[..].dSYM/[..]" ,
354
+ // Ignore Windows debub symbols files (.pdb)
355
+ "[..].pdb" ,
356
+ ]
357
+ . into_iter ( )
358
+ . map ( ToString :: to_string)
359
+ . collect ( )
360
+ }
361
+
293
362
/// Get the filename for a library.
294
363
///
295
364
/// `kind` should be one of:
0 commit comments