summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/main.rs8
-rw-r--r--cli/tools/clean.rs97
-rw-r--r--cli/tools/mod.rs1
-rw-r--r--cli/util/progress_bar/mod.rs17
-rw-r--r--cli/util/progress_bar/renderer.rs23
-rw-r--r--tests/specs/clean/general/__test__.jsonc2
7 files changed, 132 insertions, 18 deletions
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 0e7050d92..ebbe042d1 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -157,6 +157,7 @@ tower-lsp.workspace = true
twox-hash.workspace = true
typed-arena = "=2.0.2"
uuid = { workspace = true, features = ["serde"] }
+walkdir = "=2.3.2"
which.workspace = true
zeromq.workspace = true
zip = { version = "2.1.6", default-features = false, features = ["deflate-flate2"] }
@@ -173,7 +174,6 @@ nix.workspace = true
deno_bench_util.workspace = true
pretty_assertions.workspace = true
test_util.workspace = true
-walkdir = "=2.3.2"
[package.metadata.winres]
# This section defines the metadata that appears in the deno.exe PE header.
diff --git a/cli/main.rs b/cli/main.rs
index 1b2640758..e8ecaa393 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -32,7 +32,6 @@ use crate::args::flags_from_vec;
use crate::args::DenoSubcommand;
use crate::args::Flags;
use crate::args::DENO_FUTURE;
-use crate::cache::DenoDir;
use crate::graph_container::ModuleGraphContainer;
use crate::util::display;
use crate::util::v8::get_v8_flags_from_env;
@@ -138,12 +137,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
.await
}),
DenoSubcommand::Clean => spawn_subcommand(async move {
- let deno_dir = DenoDir::new(None)?;
- if deno_dir.root.exists() {
- std::fs::remove_dir_all(&deno_dir.root)?;
- log::info!("{} {}", colors::green("Removed"), deno_dir.root.display());
- }
- Ok::<(), std::io::Error>(())
+ tools::clean::clean()
}),
DenoSubcommand::Compile(compile_flags) => spawn_subcommand(async {
tools::compile::compile(flags, compile_flags).await
diff --git a/cli/tools/clean.rs b/cli/tools/clean.rs
new file mode 100644
index 000000000..2a77434f8
--- /dev/null
+++ b/cli/tools/clean.rs
@@ -0,0 +1,97 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::anyhow::Context;
+use deno_core::error::AnyError;
+use std::path::Path;
+
+use crate::cache::DenoDir;
+use crate::colors;
+use crate::display;
+use crate::util::progress_bar::ProgressBar;
+use crate::util::progress_bar::ProgressBarStyle;
+use crate::util::progress_bar::ProgressMessagePrompt;
+use crate::util::progress_bar::UpdateGuard;
+
+struct CleanState {
+ files_removed: u64,
+ dirs_removed: u64,
+ bytes_removed: u64,
+ progress_guard: UpdateGuard,
+}
+
+impl CleanState {
+ fn update_progress(&self) {
+ self
+ .progress_guard
+ .set_position(self.files_removed + self.dirs_removed);
+ }
+}
+
+pub fn clean() -> Result<(), AnyError> {
+ let deno_dir = DenoDir::new(None)?;
+ if deno_dir.root.exists() {
+ let no_of_files = walkdir::WalkDir::new(&deno_dir.root).into_iter().count();
+ let progress_bar = ProgressBar::new(ProgressBarStyle::ProgressBars);
+ let progress_guard =
+ progress_bar.update_with_prompt(ProgressMessagePrompt::Cleaning, "");
+
+ let mut state = CleanState {
+ files_removed: 0,
+ dirs_removed: 0,
+ bytes_removed: 0,
+ progress_guard,
+ };
+ state
+ .progress_guard
+ .set_total_size(no_of_files.try_into().unwrap());
+
+ rm_rf(&mut state, &deno_dir.root)?;
+
+ // Drop the guard so that progress bar disappears.
+ drop(state.progress_guard);
+
+ log::info!(
+ "{} {} {}",
+ colors::green("Removed"),
+ deno_dir.root.display(),
+ colors::gray(&format!(
+ "({} files, {})",
+ state.files_removed + state.dirs_removed,
+ display::human_size(state.bytes_removed as f64)
+ ))
+ );
+ }
+
+ Ok(())
+}
+
+fn rm_rf(state: &mut CleanState, path: &Path) -> Result<(), AnyError> {
+ for entry in walkdir::WalkDir::new(path).contents_first(true) {
+ let entry = entry?;
+
+ if entry.file_type().is_dir() {
+ state.dirs_removed += 1;
+ state.update_progress();
+ std::fs::remove_dir_all(entry.path())?;
+ } else {
+ remove_file(state, entry.path(), entry.metadata().ok())?;
+ }
+ }
+
+ Ok(())
+}
+
+fn remove_file(
+ state: &mut CleanState,
+ path: &Path,
+ meta: Option<std::fs::Metadata>,
+) -> Result<(), AnyError> {
+ if let Some(meta) = meta {
+ state.bytes_removed += meta.len();
+ }
+ state.files_removed += 1;
+ state.update_progress();
+ std::fs::remove_file(path)
+ .with_context(|| format!("Failed to remove file: {}", path.display()))?;
+ Ok(())
+}
diff --git a/cli/tools/mod.rs b/cli/tools/mod.rs
index 4593092ed..7bb9b7cf6 100644
--- a/cli/tools/mod.rs
+++ b/cli/tools/mod.rs
@@ -3,6 +3,7 @@
pub mod bench;
pub mod bundle;
pub mod check;
+pub mod clean;
pub mod compile;
pub mod coverage;
pub mod doc;
diff --git a/cli/util/progress_bar/mod.rs b/cli/util/progress_bar/mod.rs
index 91bf4950f..85be056d8 100644
--- a/cli/util/progress_bar/mod.rs
+++ b/cli/util/progress_bar/mod.rs
@@ -28,6 +28,7 @@ pub enum ProgressMessagePrompt {
Download,
Blocking,
Initialize,
+ Cleaning,
}
impl ProgressMessagePrompt {
@@ -38,6 +39,7 @@ impl ProgressMessagePrompt {
ProgressMessagePrompt::Initialize => {
colors::green("Initialize").to_string()
}
+ ProgressMessagePrompt::Cleaning => colors::green("Cleaning").to_string(),
}
}
}
@@ -71,7 +73,13 @@ impl UpdateGuard {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ProgressBarStyle {
+ /// Shows a progress bar with human readable download size
DownloadBars,
+
+ /// Shows a progress bar with numeric progres count
+ ProgressBars,
+
+ /// Shows a list of currently downloaded files.
TextOnly,
}
@@ -270,7 +278,14 @@ impl ProgressBar {
Self {
inner: ProgressBarInner::new(match style {
ProgressBarStyle::DownloadBars => {
- Arc::new(renderer::BarProgressBarRenderer)
+ Arc::new(renderer::BarProgressBarRenderer {
+ display_human_download_size: true,
+ })
+ }
+ ProgressBarStyle::ProgressBars => {
+ Arc::new(renderer::BarProgressBarRenderer {
+ display_human_download_size: false,
+ })
}
ProgressBarStyle::TextOnly => {
Arc::new(renderer::TextOnlyProgressBarRenderer::default())
diff --git a/cli/util/progress_bar/renderer.rs b/cli/util/progress_bar/renderer.rs
index 64d533979..a83ceb333 100644
--- a/cli/util/progress_bar/renderer.rs
+++ b/cli/util/progress_bar/renderer.rs
@@ -34,7 +34,9 @@ pub trait ProgressBarRenderer: Send + Sync + std::fmt::Debug {
/// Indicatif style progress bar.
#[derive(Debug)]
-pub struct BarProgressBarRenderer;
+pub struct BarProgressBarRenderer {
+ pub display_human_download_size: bool,
+}
impl ProgressBarRenderer for BarProgressBarRenderer {
fn render(&self, data: ProgressData) -> String {
@@ -48,13 +50,16 @@ impl ProgressBarRenderer for BarProgressBarRenderer {
if total_size == 0 {
(String::new(), 0)
} else {
- let total_size_str = human_download_size(total_size, total_size);
- (
- format!(
- " {}/{}",
+ let (pos_str, total_size_str) = if self.display_human_download_size {
+ (
human_download_size(pos, total_size),
- total_size_str,
- ),
+ human_download_size(total_size, total_size),
+ )
+ } else {
+ (pos.to_string(), total_size.to_string())
+ };
+ (
+ format!(" {}/{}", pos_str, total_size_str,),
2 + total_size_str.len() * 2,
)
}
@@ -244,7 +249,9 @@ mod test {
#[test]
fn should_render_bar_progress() {
- let renderer = BarProgressBarRenderer;
+ let renderer = BarProgressBarRenderer {
+ display_human_download_size: true,
+ };
let mut data = ProgressData {
display_entries: vec![ProgressDataDisplayEntry {
prompt: ProgressMessagePrompt::Download,
diff --git a/tests/specs/clean/general/__test__.jsonc b/tests/specs/clean/general/__test__.jsonc
index f425a20c1..cdc0d0b44 100644
--- a/tests/specs/clean/general/__test__.jsonc
+++ b/tests/specs/clean/general/__test__.jsonc
@@ -15,7 +15,7 @@
"output": "true\n"
}, {
"args": "clean",
- "output": "Removed [WILDLINE]/deno_dir\n"
+ "output": "Removed [WILDLINE]/deno_dir ([WILDCARD]files, [WILDCARD])\n"
}, {
"envs": {
// use a new dir to avoid creating the old one