Skip to content

Commit 1ac83ba

Browse files
committed
Auto merge of #11008 - weihanglo:issue-10917, r=epage
Ignore broken but excluded file during traversing
2 parents 6066463 + c0110c6 commit 1ac83ba

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

src/cargo/sources/path.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ impl<'cfg> PathSource<'cfg> {
150150
}
151151
};
152152

153-
let mut filter = |path: &Path, is_dir: bool| {
153+
let filter = |path: &Path, is_dir: bool| {
154154
let relative_path = match path.strip_prefix(root) {
155155
Ok(p) => p,
156156
Err(_) => return false,
@@ -169,10 +169,10 @@ impl<'cfg> PathSource<'cfg> {
169169
// Attempt Git-prepopulate only if no `include` (see rust-lang/cargo#4135).
170170
if no_include_option {
171171
if let Some(repo) = git_repo {
172-
return self.list_files_git(pkg, &repo, &mut filter);
172+
return self.list_files_git(pkg, &repo, &filter);
173173
}
174174
}
175-
self.list_files_walk(pkg, &mut filter)
175+
self.list_files_walk(pkg, &filter)
176176
}
177177

178178
/// Returns `Some(git2::Repository)` if found sibling `Cargo.toml` and `.git`
@@ -222,7 +222,7 @@ impl<'cfg> PathSource<'cfg> {
222222
&self,
223223
pkg: &Package,
224224
repo: &git2::Repository,
225-
filter: &mut dyn FnMut(&Path, bool) -> bool,
225+
filter: &dyn Fn(&Path, bool) -> bool,
226226
) -> CargoResult<Vec<PathBuf>> {
227227
warn!("list_files_git {}", pkg.package_id());
228228
let index = repo.index()?;
@@ -376,7 +376,7 @@ impl<'cfg> PathSource<'cfg> {
376376
fn list_files_walk(
377377
&self,
378378
pkg: &Package,
379-
filter: &mut dyn FnMut(&Path, bool) -> bool,
379+
filter: &dyn Fn(&Path, bool) -> bool,
380380
) -> CargoResult<Vec<PathBuf>> {
381381
let mut ret = Vec::new();
382382
self.walk(pkg.root(), &mut ret, true, filter)?;
@@ -388,7 +388,7 @@ impl<'cfg> PathSource<'cfg> {
388388
path: &Path,
389389
ret: &mut Vec<PathBuf>,
390390
is_root: bool,
391-
filter: &mut dyn FnMut(&Path, bool) -> bool,
391+
filter: &dyn Fn(&Path, bool) -> bool,
392392
) -> CargoResult<()> {
393393
let walkdir = WalkDir::new(path)
394394
.follow_links(true)
@@ -432,7 +432,11 @@ impl<'cfg> PathSource<'cfg> {
432432
self.config.shell().warn(err)?;
433433
}
434434
Err(err) => match err.path() {
435-
// If the error occurs with a path, simply recover from it.
435+
// If an error occurs with a path, filter it again.
436+
// If it is excluded, Just ignore it in this case.
437+
// See issue rust-lang/cargo#10917
438+
Some(path) if !filter(path, path.is_dir()) => {}
439+
// Otherwise, simply recover from it.
436440
// Don't worry about error skipping here, the callers would
437441
// still hit the IO error if they do access it thereafter.
438442
Some(path) => ret.push(path.to_path_buf()),

tests/testsuite/package.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,55 @@ Caused by:
845845
.run();
846846
}
847847

848+
#[cargo_test]
849+
/// Tests if a broken but excluded symlink is ignored.
850+
/// See issue rust-lang/cargo#10917
851+
///
852+
/// This test requires you to be able to make symlinks.
853+
/// For windows, this may require you to enable developer mode.
854+
fn broken_but_excluded_symlink() {
855+
#[cfg(unix)]
856+
use std::os::unix::fs::symlink;
857+
#[cfg(windows)]
858+
use std::os::windows::fs::symlink_dir as symlink;
859+
860+
if !symlink_supported() {
861+
return;
862+
}
863+
864+
let p = project()
865+
.file(
866+
"Cargo.toml",
867+
r#"
868+
[project]
869+
name = "foo"
870+
version = "0.0.1"
871+
authors = []
872+
license = "MIT"
873+
description = 'foo'
874+
documentation = 'foo'
875+
homepage = 'foo'
876+
repository = 'foo'
877+
exclude = ["src/foo.rs"]
878+
"#,
879+
)
880+
.file("src/main.rs", r#"fn main() { println!("hello"); }"#)
881+
.build();
882+
t!(symlink("nowhere", &p.root().join("src/foo.rs")));
883+
884+
p.cargo("package -v --list")
885+
// `src/foo.rs` is excluded.
886+
.with_stdout(
887+
"\
888+
Cargo.lock
889+
Cargo.toml
890+
Cargo.toml.orig
891+
src/main.rs
892+
",
893+
)
894+
.run();
895+
}
896+
848897
#[cargo_test]
849898
#[cfg(not(windows))] // https://github.com/libgit2/libgit2/issues/6250
850899
/// Test that /dir and /dir/ matches symlinks to directories.

0 commit comments

Comments
 (0)