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 ;
@@ -11,8 +10,8 @@ use anyhow::Context as _;
11
10
use cargo_util:: paths;
12
11
use filetime:: FileTime ;
13
12
use ignore:: gitignore:: GitignoreBuilder ;
14
- use ignore:: Match ;
15
13
use log:: { trace, warn} ;
14
+ use walkdir:: WalkDir ;
16
15
17
16
pub struct PathSource < ' cfg > {
18
17
source_id : SourceId ,
@@ -131,39 +130,36 @@ impl<'cfg> PathSource<'cfg> {
131
130
}
132
131
let ignore_include = include_builder. build ( ) ?;
133
132
134
- let ignore_should_package = |relative_path : & Path , is_dir : bool | -> CargoResult < bool > {
133
+ let ignore_should_package = |relative_path : & Path , is_dir : bool | {
135
134
// "Include" and "exclude" options are mutually exclusive.
136
135
if no_include_option {
137
- match ignore_exclude. matched_path_or_any_parents ( relative_path, is_dir) {
138
- Match :: None => Ok ( true ) ,
139
- Match :: Ignore ( _) => Ok ( false ) ,
140
- Match :: Whitelist ( _) => Ok ( true ) ,
141
- }
136
+ !ignore_exclude
137
+ . matched_path_or_any_parents ( relative_path, is_dir)
138
+ . is_ignore ( )
142
139
} else {
143
140
if is_dir {
144
141
// Generally, include directives don't list every
145
142
// directory (nor should they!). Just skip all directory
146
143
// checks, and only check files.
147
- return Ok ( true ) ;
144
+ return true ;
148
145
}
149
- match ignore_include
146
+ ignore_include
150
147
. matched_path_or_any_parents ( relative_path, /* is_dir */ false )
151
- {
152
- Match :: None => Ok ( false ) ,
153
- Match :: Ignore ( _) => Ok ( true ) ,
154
- Match :: Whitelist ( _) => Ok ( false ) ,
155
- }
148
+ . is_ignore ( )
156
149
}
157
150
} ;
158
151
159
- let mut filter = |path : & Path , is_dir : bool | -> CargoResult < bool > {
160
- let relative_path = path. strip_prefix ( root) ?;
152
+ let mut filter = |path : & Path , is_dir : bool | {
153
+ let relative_path = match path. strip_prefix ( root) {
154
+ Ok ( p) => p,
155
+ Err ( _) => return false ,
156
+ } ;
161
157
162
158
let rel = relative_path. as_os_str ( ) ;
163
159
if rel == "Cargo.lock" {
164
- return Ok ( pkg. include_lockfile ( ) ) ;
160
+ return pkg. include_lockfile ( ) ;
165
161
} else if rel == "Cargo.toml" {
166
- return Ok ( true ) ;
162
+ return true ;
167
163
}
168
164
169
165
ignore_should_package ( relative_path, is_dir)
@@ -225,7 +221,7 @@ impl<'cfg> PathSource<'cfg> {
225
221
& self ,
226
222
pkg : & Package ,
227
223
repo : & git2:: Repository ,
228
- filter : & mut dyn FnMut ( & Path , bool ) -> CargoResult < bool > ,
224
+ filter : & mut dyn FnMut ( & Path , bool ) -> bool ,
229
225
) -> CargoResult < Vec < PathBuf > > {
230
226
warn ! ( "list_files_git {}" , pkg. package_id( ) ) ;
231
227
let index = repo. index ( ) ?;
@@ -347,7 +343,7 @@ impl<'cfg> PathSource<'cfg> {
347
343
PathSource :: walk ( & file_path, & mut ret, false , filter) ?;
348
344
}
349
345
}
350
- } else if ( * filter) ( & file_path, is_dir) ? {
346
+ } else if filter ( & file_path, is_dir) {
351
347
assert ! ( !is_dir) ;
352
348
// We found a file!
353
349
warn ! ( " found {}" , file_path. display( ) ) ;
@@ -379,7 +375,7 @@ impl<'cfg> PathSource<'cfg> {
379
375
fn list_files_walk (
380
376
& self ,
381
377
pkg : & Package ,
382
- filter : & mut dyn FnMut ( & Path , bool ) -> CargoResult < bool > ,
378
+ filter : & mut dyn FnMut ( & Path , bool ) -> bool ,
383
379
) -> CargoResult < Vec < PathBuf > > {
384
380
let mut ret = Vec :: new ( ) ;
385
381
PathSource :: walk ( pkg. root ( ) , & mut ret, true , filter) ?;
@@ -390,39 +386,46 @@ impl<'cfg> PathSource<'cfg> {
390
386
path : & Path ,
391
387
ret : & mut Vec < PathBuf > ,
392
388
is_root : bool ,
393
- filter : & mut dyn FnMut ( & Path , bool ) -> CargoResult < bool > ,
389
+ filter : & mut dyn FnMut ( & Path , bool ) -> bool ,
394
390
) -> 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
- }
391
+ let walkdir = WalkDir :: new ( path)
392
+ . follow_links ( true )
393
+ . into_iter ( )
394
+ . filter_entry ( |entry| {
395
+ let path = entry. path ( ) ;
396
+ let at_root = is_root && entry. depth ( ) == 0 ;
397
+ let is_dir = entry. file_type ( ) . is_dir ( ) ;
398
+
399
+ if !at_root && !filter ( path, is_dir) {
400
+ return false ;
401
+ }
407
402
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 ;
403
+ if !is_dir {
404
+ return true ;
405
+ }
406
+
407
+ // Don't recurse into any sub-packages that we have.
408
+ if !at_root && path. join ( "Cargo.toml" ) . exists ( ) {
409
+ return false ;
410
+ }
411
+
412
+ // Skip root Cargo artifacts.
413
+ if is_root
414
+ && entry. depth ( ) == 1
415
+ && path. file_name ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "target" )
416
+ {
417
+ return false ;
418
+ }
419
+
420
+ true
421
+ } ) ;
422
+ for entry in walkdir {
423
+ let entry = entry?;
424
+ if !entry. file_type ( ) . is_dir ( ) {
425
+ ret. push ( entry. path ( ) . to_path_buf ( ) ) ;
423
426
}
424
- PathSource :: walk ( & path, ret, false , filter) ?;
425
427
}
428
+
426
429
Ok ( ( ) )
427
430
}
428
431
0 commit comments