1
1
use std:: collections:: HashSet ;
2
2
use std:: fmt:: { self , Debug , Formatter } ;
3
- use std:: fs;
4
3
use std:: path:: { Path , PathBuf } ;
5
4
6
5
use crate :: core:: source:: MaybePackage ;
@@ -13,6 +12,7 @@ use filetime::FileTime;
13
12
use ignore:: gitignore:: GitignoreBuilder ;
14
13
use ignore:: Match ;
15
14
use log:: { trace, warn} ;
15
+ use walkdir:: WalkDir ;
16
16
17
17
pub struct PathSource < ' cfg > {
18
18
source_id : SourceId ,
@@ -392,37 +392,44 @@ impl<'cfg> PathSource<'cfg> {
392
392
is_root : bool ,
393
393
filter : & mut dyn FnMut ( & Path , bool ) -> CargoResult < bool > ,
394
394
) -> CargoResult < ( ) > {
395
- let is_dir = path. is_dir ( ) ;
396
- if !is_root && !( * filter) ( path, is_dir) ? {
397
- return Ok ( ( ) ) ;
398
- }
399
- if !is_dir {
400
- ret. push ( path. to_path_buf ( ) ) ;
401
- return Ok ( ( ) ) ;
402
- }
403
- // Don't recurse into any sub-packages that we have.
404
- if !is_root && path. join ( "Cargo.toml" ) . exists ( ) {
405
- return Ok ( ( ) ) ;
406
- }
395
+ let walkdir = WalkDir :: new ( path)
396
+ . follow_links ( true )
397
+ . into_iter ( )
398
+ . filter_entry ( |entry| {
399
+ let path = entry. path ( ) ;
400
+ let at_root = is_root && entry. depth ( ) == 0 ;
401
+ let is_dir = entry. file_type ( ) . is_dir ( ) ;
402
+
403
+ if !at_root && !filter ( path, is_dir) . unwrap ( ) {
404
+ return false ;
405
+ }
407
406
408
- // For package integration tests, we need to sort the paths in a deterministic order to
409
- // be able to match stdout warnings in the same order.
410
- //
411
- // TODO: drop `collect` and sort after transition period and dropping warning tests.
412
- // See rust-lang/cargo#4268 and rust-lang/cargo#4270.
413
- let mut entries: Vec < PathBuf > = fs:: read_dir ( path)
414
- . with_context ( || format ! ( "cannot read {:?}" , path) ) ?
415
- . map ( |e| e. unwrap ( ) . path ( ) )
416
- . collect ( ) ;
417
- entries. sort_unstable_by ( |a, b| a. as_os_str ( ) . cmp ( b. as_os_str ( ) ) ) ;
418
- for path in entries {
419
- let name = path. file_name ( ) . and_then ( |s| s. to_str ( ) ) ;
420
- if is_root && name == Some ( "target" ) {
421
- // Skip Cargo artifacts.
422
- continue ;
407
+ if !is_dir {
408
+ return true ;
409
+ }
410
+
411
+ // Don't recurse into any sub-packages that we have.
412
+ if !at_root && path. join ( "Cargo.toml" ) . exists ( ) {
413
+ return false ;
414
+ }
415
+
416
+ // Skip root Cargo artifacts.
417
+ if is_root
418
+ && entry. depth ( ) == 1
419
+ && path. file_name ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "target" )
420
+ {
421
+ return false ;
422
+ }
423
+
424
+ true
425
+ } ) ;
426
+ for entry in walkdir {
427
+ let entry = entry?;
428
+ if !entry. file_type ( ) . is_dir ( ) {
429
+ ret. push ( entry. path ( ) . to_path_buf ( ) ) ;
423
430
}
424
- PathSource :: walk ( & path, ret, false , filter) ?;
425
431
}
432
+
426
433
Ok ( ( ) )
427
434
}
428
435
0 commit comments