Skip to content

Commit 4d46ffb

Browse files
committed
Add a progress indicator for cargo clean
1 parent 1f12b88 commit 4d46ffb

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/cargo/ops/cargo_clean.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ops;
55
use crate::util::errors::CargoResult;
66
use crate::util::interning::InternedString;
77
use crate::util::lev_distance;
8-
use crate::util::Config;
8+
use crate::util::{Config, Progress, ProgressStyle};
99

1010
use anyhow::Context as _;
1111
use cargo_util::paths;
@@ -33,8 +33,9 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
3333

3434
// If the doc option is set, we just want to delete the doc directory.
3535
if opts.doc {
36+
let mut progress = Progress::with_style("Cleaning", ProgressStyle::Percentage, config);
3637
target_dir = target_dir.join("doc");
37-
return rm_rf(&target_dir.into_path_unlocked(), config);
38+
return rm_rf_with_progress(&target_dir.into_path_unlocked(), &mut progress);
3839
}
3940

4041
let profiles = Profiles::new(ws, opts.requested_profile)?;
@@ -53,7 +54,8 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
5354
// Note that we don't bother grabbing a lock here as we're just going to
5455
// blow it all away anyway.
5556
if opts.spec.is_empty() {
56-
return rm_rf(&target_dir.into_path_unlocked(), config);
57+
let mut progress = Progress::with_style("Cleaning", ProgressStyle::Percentage, config);
58+
return rm_rf_with_progress(&target_dir.into_path_unlocked(), &mut progress);
5759
}
5860

5961
// Clean specific packages.
@@ -133,8 +135,10 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
133135
}
134136
let packages = pkg_set.get_many(pkg_ids)?;
135137

136-
for pkg in packages {
138+
let mut progress = Progress::with_style("Cleaning", ProgressStyle::Ratio, config);
139+
for (pkg_idx, pkg) in packages.iter().enumerate() {
137140
let pkg_dir = format!("{}-*", pkg.name());
141+
progress.tick_now(pkg_idx + 1, packages.len(), &format!(": {}", pkg.name()))?;
138142

139143
// Clean fingerprints.
140144
for (_, layout) in &layouts_with_host {
@@ -231,6 +235,25 @@ fn rm_rf_glob(pattern: &Path, config: &Config) -> CargoResult<()> {
231235
Ok(())
232236
}
233237

238+
fn rm_rf_with_progress(path: &Path, progress: &mut Progress<'_>) -> CargoResult<()> {
239+
let num_paths = walkdir::WalkDir::new(path).into_iter().count();
240+
for (idx, entry) in walkdir::WalkDir::new(path)
241+
.contents_first(true)
242+
.into_iter()
243+
.enumerate()
244+
{
245+
progress.tick(std::cmp::min(idx + 1, num_paths), num_paths, "")?;
246+
if let Ok(entry) = entry {
247+
if entry.file_type().is_dir() {
248+
paths::remove_dir(entry.path())?;
249+
} else {
250+
paths::remove_file(entry.path())?;
251+
}
252+
}
253+
}
254+
Ok(())
255+
}
256+
234257
fn rm_rf(path: &Path, config: &Config) -> CargoResult<()> {
235258
let m = fs::symlink_metadata(path);
236259
if m.as_ref().map(|s| s.is_dir()).unwrap_or(false) {

0 commit comments

Comments
 (0)