Skip to content

Commit 3591a5b

Browse files
committed
Use walkdir to walk filesyste and detect loop
1 parent a359ce1 commit 3591a5b

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

src/cargo/sources/path.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::collections::HashSet;
22
use std::fmt::{self, Debug, Formatter};
3-
use std::fs;
43
use std::path::{Path, PathBuf};
54

65
use crate::core::source::MaybePackage;
@@ -13,6 +12,7 @@ use filetime::FileTime;
1312
use ignore::gitignore::GitignoreBuilder;
1413
use ignore::Match;
1514
use log::{trace, warn};
15+
use walkdir::WalkDir;
1616

1717
pub struct PathSource<'cfg> {
1818
source_id: SourceId,
@@ -392,37 +392,44 @@ impl<'cfg> PathSource<'cfg> {
392392
is_root: bool,
393393
filter: &mut dyn FnMut(&Path, bool) -> CargoResult<bool>,
394394
) -> 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+
}
407406

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());
423430
}
424-
PathSource::walk(&path, ret, false, filter)?;
425431
}
432+
426433
Ok(())
427434
}
428435

0 commit comments

Comments
 (0)