Skip to content

Commit

Permalink
Add --extracted to cache prune
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jul 24, 2024
1 parent 41b699e commit b758cbc
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
30 changes: 29 additions & 1 deletion crates/uv-cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl Cache {
}

/// Run the garbage collector on the cache, removing any dangling entries.
pub fn prune(&self) -> Result<Removal, io::Error> {
pub fn prune(&self, all_unzipped: bool) -> Result<Removal, io::Error> {
let mut summary = Removal::default();

// First, remove any top-level directories that are unused. These typically represent
Expand Down Expand Up @@ -386,6 +386,34 @@ impl Cache {
Err(err) => return Err(err),
}

// Third, if enabled, remove all unzipped wheels, leaving only the wheel archives.
if all_unzipped {
// Remove the entire pre-built wheel cache, since every entry is an unzipped wheel.
match fs::read_dir(self.bucket(CacheBucket::Wheels)) {
Ok(entries) => {
for entry in entries {
let entry = entry?;
let path = fs_err::canonicalize(entry.path())?;
if path.is_dir() {
debug!("Removing unzipped wheel entry: {}", path.display());
summary += rm_rf(path)?;
}
}
}
Err(err) if err.kind() == io::ErrorKind::NotFound => (),
Err(err) => return Err(err),
}

// Remove any unzipped wheels (i.e., symlinks) from the built wheels cache.
for entry in walkdir::WalkDir::new(self.bucket(CacheBucket::SourceDistributions)) {
let entry = entry?;
if entry.file_type().is_symlink() {
debug!("Removing unzipped wheel entry: {}", entry.path().display());
summary += rm_rf(entry.path())?;
}
}
}

// Third, remove any unused archives (by searching for archives that are not symlinked).
// TODO(charlie): Remove any unused source distributions. This requires introspecting the
// cache contents, e.g., reading and deserializing the manifests.
Expand Down
16 changes: 15 additions & 1 deletion crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ pub enum CacheCommand {
/// Clear the cache, removing all entries or those linked to specific packages.
Clean(CleanArgs),
/// Prune all unreachable objects from the cache.
Prune,
Prune(PruneArgs),
/// Show the cache directory.
Dir,
}
Expand All @@ -291,6 +291,20 @@ pub struct CleanArgs {
pub package: Vec<PackageName>,
}

#[derive(Args, Debug)]
#[allow(clippy::struct_excessive_bools)]
pub struct PruneArgs {
/// Whether to remove unzipped wheels from the cache, leaving only zipped wheel entries.
///
/// By default, uv stores unzipped wheels in the cache, which enables high-performance package
/// installation. In some scenarios, though, persisting unzipped wheels may be undesirable. For
/// example, in GitHub Actions or other CI environments, uploading unzipped wheels to a remote
/// cache may have a negative impact on cache performance. Pruning unzipped wheels will leave
/// the cache with any built wheels in their zipped form.
#[arg(long)]
pub all_unzipped: bool,
}

#[derive(Args)]
#[allow(clippy::struct_excessive_bools)]
pub struct PipNamespace {
Expand Down
2 changes: 1 addition & 1 deletion crates/uv-distribution/src/distribution_database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {

// Download and unzip.
match self
.stream_wheel(
.download_wheel(
url.clone(),
&wheel.filename,
wheel.file.size,
Expand Down
8 changes: 6 additions & 2 deletions crates/uv/src/commands/cache_prune.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ use crate::commands::{human_readable_bytes, ExitStatus};
use crate::printer::Printer;

/// Prune all unreachable objects from the cache.
pub(crate) fn cache_prune(cache: &Cache, printer: Printer) -> Result<ExitStatus> {
pub(crate) fn cache_prune(
all_unzipped: bool,
cache: &Cache,
printer: Printer,
) -> Result<ExitStatus> {
if !cache.root().exists() {
writeln!(
printer.stderr(),
Expand All @@ -27,7 +31,7 @@ pub(crate) fn cache_prune(cache: &Cache, printer: Printer) -> Result<ExitStatus>
)?;

let summary = cache
.prune()
.prune(all_unzipped)
.with_context(|| format!("Failed to prune cache at: {}", cache.root().user_display()))?;

// Write a summary of the number of files and directories removed.
Expand Down
7 changes: 5 additions & 2 deletions crates/uv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,8 +538,11 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
commands::cache_clean(&args.package, &cache, printer)
}
Commands::Cache(CacheNamespace {
command: CacheCommand::Prune,
}) => commands::cache_prune(&cache, printer),
command: CacheCommand::Prune(args),
}) => {
show_settings!(args);
commands::cache_prune(args.all_unzipped, &cache, printer)
}
Commands::Cache(CacheNamespace {
command: CacheCommand::Dir,
}) => {
Expand Down

0 comments on commit b758cbc

Please sign in to comment.