mirror of
https://github.com/denoland/deno.git
synced 2025-02-01 12:16:11 -05:00
273ec9fbf2
Allows easily constructing a `DenoResolver` using the exact same logic that we use in the CLI (useful for dnt and for external bundlers). This code is then used in the CLI to ensure the logic is always up-to-date. ```rs use std::rc::Rc; use deno_resolver:🏭:ResolverFactory; use deno_resolver:🏭:WorkspaceFactory; use sys_traits::impls::RealSys; let sys = RealSys; let cwd = sys.env_current_dir()?; let workspace_factory = Rc::new(WorkspaceFactory::new(sys, cwd, Default::default())); let resolver_factory = ResolverFactory::new(workspace_factory.clone(), Default::default()); let deno_resolver = resolver_factory.deno_resolver().await?; ```
101 lines
2.5 KiB
Rust
101 lines
2.5 KiB
Rust
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
|
|
use std::path::Path;
|
|
use std::sync::Arc;
|
|
|
|
use deno_core::anyhow::Context;
|
|
use deno_core::error::AnyError;
|
|
|
|
use crate::args::Flags;
|
|
use crate::colors;
|
|
use crate::display;
|
|
use crate::factory::CliFactory;
|
|
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(flags: Arc<Flags>) -> Result<(), AnyError> {
|
|
let factory = CliFactory::from_flags(flags);
|
|
let deno_dir = factory.deno_dir()?;
|
|
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(())
|
|
}
|