From 50ba90240b1436b01743747257ad2ca955382170 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 Jul 2024 23:03:20 -0400 Subject: [PATCH] Junction --- crates/uv-cache/src/lib.rs | 4 ++-- crates/uv-cache/src/removal.rs | 9 +++++++-- crates/uv-cli/src/lib.rs | 22 ++++++++++++++-------- crates/uv/src/commands/cache_prune.rs | 4 ++-- crates/uv/src/lib.rs | 2 +- crates/uv/tests/cache_prune.rs | 4 ++-- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/crates/uv-cache/src/lib.rs b/crates/uv-cache/src/lib.rs index bf22963dda721..457a0513ee132 100644 --- a/crates/uv-cache/src/lib.rs +++ b/crates/uv-cache/src/lib.rs @@ -340,7 +340,7 @@ impl Cache { } /// Run the garbage collector on the cache, removing any dangling entries. - pub fn prune(&self, all_unzipped: bool) -> Result { + pub fn prune(&self, ci: bool) -> Result { let mut summary = Removal::default(); // First, remove any top-level directories that are unused. These typically represent @@ -387,7 +387,7 @@ impl Cache { } // Third, if enabled, remove all unzipped wheels, leaving only the wheel archives. - if all_unzipped { + if ci { // Remove the entire pre-built wheel cache, since every entry is an unzipped wheel. match fs::read_dir(self.bucket(CacheBucket::Wheels)) { Ok(entries) => { diff --git a/crates/uv-cache/src/removal.rs b/crates/uv-cache/src/removal.rs index c54ce81b5aef7..156f48a3832bf 100644 --- a/crates/uv-cache/src/removal.rs +++ b/crates/uv-cache/src/removal.rs @@ -40,7 +40,12 @@ impl Removal { // Remove the file. self.total_bytes += metadata.len(); - remove_file(path)?; + if cfg!(windows) && metadata.is_symlink() { + // Remove the junction. + remove_dir(path)?; + } else { + remove_file(path)?; + } return Ok(()); } @@ -64,7 +69,7 @@ impl Removal { let entry = entry?; if cfg!(windows) && entry.file_type().is_symlink() { - // In this branch, we try to handle junction removal. + // Remove the junction. self.num_files += 1; remove_dir(entry.path())?; } else if entry.file_type().is_dir() { diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 50be1b8e4d609..a79e747535ff8 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -294,15 +294,21 @@ pub struct CleanArgs { #[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. + /// Optimize the cache for persistence in a continuous integration environment, like GitHub + /// Actions. + /// + /// By default, uv caches both the wheels that it builds from source and the pre-built wheels + /// that it downloads directly, to enable high-performance package installation. In some + /// scenarios, though, persisting pre-built wheels may be undesirable. For example, in GitHub + /// Actions, it's faster to omit pre-built wheels from the cache and instead have re-download + /// them on each run. However, it typically _is_ faster to cache wheels that are built from + /// source, since the wheel building process can be expensive, especially for extension + /// modules. + /// + /// In `--ci` mode, uv will prune any pre-built wheels from the cache, but retain any wheels + /// that were built from source. #[arg(long)] - pub all_unzipped: bool, + pub ci: bool, } #[derive(Args)] diff --git a/crates/uv/src/commands/cache_prune.rs b/crates/uv/src/commands/cache_prune.rs index 3de1eef3c83df..73587a85c40cf 100644 --- a/crates/uv/src/commands/cache_prune.rs +++ b/crates/uv/src/commands/cache_prune.rs @@ -11,7 +11,7 @@ use crate::printer::Printer; /// Prune all unreachable objects from the cache. pub(crate) fn cache_prune( - all_unzipped: bool, + ci: bool, cache: &Cache, printer: Printer, ) -> Result { @@ -31,7 +31,7 @@ pub(crate) fn cache_prune( )?; let summary = cache - .prune(all_unzipped) + .prune(ci) .with_context(|| format!("Failed to prune cache at: {}", cache.root().user_display()))?; // Write a summary of the number of files and directories removed. diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 9e6e953bf5746..dc7c06a535e65 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -541,7 +541,7 @@ async fn run(cli: Cli) -> Result { command: CacheCommand::Prune(args), }) => { show_settings!(args); - commands::cache_prune(args.all_unzipped, &cache, printer) + commands::cache_prune(args.ci, &cache, printer) } Commands::Cache(CacheNamespace { command: CacheCommand::Dir, diff --git a/crates/uv/tests/cache_prune.rs b/crates/uv/tests/cache_prune.rs index d121cdafa345b..24471a806cf98 100644 --- a/crates/uv/tests/cache_prune.rs +++ b/crates/uv/tests/cache_prune.rs @@ -172,7 +172,7 @@ fn prune_stale_symlink() -> Result<()> { Ok(()) } -/// `cache prune --all-unzips` should remove all unzipped archives. +/// `cache prune --ci` should remove all unzipped archives. #[test] fn prune_unzipped() -> Result<()> { let context = TestContext::new("3.12"); @@ -195,7 +195,7 @@ fn prune_unzipped() -> Result<()> { + source-distribution==0.0.1 "###); - uv_snapshot!(context.filters(), context.prune().arg("--all-unzipped"), @r###" + uv_snapshot!(context.filters(), context.prune().arg("--ci"), @r###" success: true exit_code: 0 ----- stdout -----