Skip to content

Commit 58b22f0

Browse files
committed
Auto merge of #11442 - trevyn:issue-11441, r=weihanglo
cargo clean: use `remove_dir_all` Fixes #11441
2 parents 9b85e11 + ac3ccdd commit 58b22f0

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

crates/cargo-util/src/paths.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,22 @@ fn _create_dir_all(p: &Path) -> Result<()> {
413413
Ok(())
414414
}
415415

416-
/// Recursively remove all files and directories at the given directory.
416+
/// Equivalent to [`std::fs::remove_dir_all`] with better error messages.
417417
///
418418
/// This does *not* follow symlinks.
419419
pub fn remove_dir_all<P: AsRef<Path>>(p: P) -> Result<()> {
420-
_remove_dir_all(p.as_ref())
420+
_remove_dir_all(p.as_ref()).or_else(|prev_err| {
421+
// `std::fs::remove_dir_all` is highly specialized for different platforms
422+
// and may be more reliable than a simple walk. We try the walk first in
423+
// order to report more detailed errors.
424+
fs::remove_dir_all(p.as_ref()).with_context(|| {
425+
format!(
426+
"{:?}\n\nError: failed to remove directory `{}`",
427+
prev_err,
428+
p.as_ref().display(),
429+
)
430+
})
431+
})
421432
}
422433

423434
fn _remove_dir_all(p: &Path) -> Result<()> {

src/cargo/ops/cargo_clean.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,12 @@ fn rm_rf(path: &Path, config: &Config, progress: &mut dyn CleaningProgressBar) -
297297
let entry = entry?;
298298
progress.on_clean()?;
299299
if entry.file_type().is_dir() {
300-
paths::remove_dir(entry.path()).with_context(|| "could not remove build directory")?;
300+
// The contents should have been removed by now, but sometimes a race condition is hit
301+
// where other files have been added by the OS. `paths::remove_dir_all` also falls back
302+
// to `std::fs::remove_dir_all`, which may be more reliable than a simple walk in
303+
// platform-specific edge cases.
304+
paths::remove_dir_all(entry.path())
305+
.with_context(|| "could not remove build directory")?;
301306
} else {
302307
paths::remove_file(entry.path()).with_context(|| "failed to remove build artifact")?;
303308
}

0 commit comments

Comments
 (0)