mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-01 20:31:12 +00:00
Add --force flag for uv cache prune (#16137)
Matching #15992 See https://github.com/astral-sh/setup-uv/issues/588
This commit is contained in:
parent
3bed81866f
commit
7e4edf0fb4
5 changed files with 81 additions and 3 deletions
|
|
@ -802,6 +802,13 @@ pub struct PruneArgs {
|
|||
/// that were built from source.
|
||||
#[arg(long)]
|
||||
pub ci: bool,
|
||||
|
||||
/// Force removal of the cache, ignoring in-use checks.
|
||||
///
|
||||
/// By default, `uv cache prune` will block until no process is reading the cache. When
|
||||
/// `--force` is used, `uv cache prune` will proceed without taking a lock.
|
||||
#[arg(long)]
|
||||
pub force: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use std::fmt::Write;
|
|||
|
||||
use anyhow::{Context, Result};
|
||||
use owo_colors::OwoColorize;
|
||||
use tracing::debug;
|
||||
|
||||
use uv_cache::{Cache, Removal};
|
||||
use uv_fs::Simplified;
|
||||
|
|
@ -10,7 +11,12 @@ use crate::commands::{ExitStatus, human_readable_bytes};
|
|||
use crate::printer::Printer;
|
||||
|
||||
/// Prune all unreachable objects from the cache.
|
||||
pub(crate) fn cache_prune(ci: bool, cache: Cache, printer: Printer) -> Result<ExitStatus> {
|
||||
pub(crate) fn cache_prune(
|
||||
ci: bool,
|
||||
force: bool,
|
||||
cache: Cache,
|
||||
printer: Printer,
|
||||
) -> Result<ExitStatus> {
|
||||
if !cache.root().exists() {
|
||||
writeln!(
|
||||
printer.stderr(),
|
||||
|
|
@ -19,7 +25,19 @@ pub(crate) fn cache_prune(ci: bool, cache: Cache, printer: Printer) -> Result<Ex
|
|||
)?;
|
||||
return Ok(ExitStatus::Success);
|
||||
}
|
||||
let cache = cache.with_exclusive_lock()?;
|
||||
|
||||
let cache = if force {
|
||||
// If `--force` is used, attempt to acquire the exclusive lock but do not block.
|
||||
match cache.with_exclusive_lock_no_wait() {
|
||||
Ok(cache) => cache,
|
||||
Err(cache) => {
|
||||
debug!("Cache is currently in use, proceeding due to `--force`");
|
||||
cache
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cache.with_exclusive_lock()?
|
||||
};
|
||||
|
||||
writeln!(
|
||||
printer.stderr(),
|
||||
|
|
|
|||
|
|
@ -1023,7 +1023,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
command: CacheCommand::Prune(args),
|
||||
}) => {
|
||||
show_settings!(args);
|
||||
commands::cache_prune(args.ci, cache, printer)
|
||||
commands::cache_prune(args.ci, args.force, cache, printer)
|
||||
}
|
||||
Commands::Cache(CacheNamespace {
|
||||
command: CacheCommand::Dir,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,57 @@ fn prune_stale_symlink() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prune_force() -> Result<()> {
|
||||
let context = TestContext::new("3.12").with_filtered_counts();
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("typing-extensions\niniconfig")?;
|
||||
|
||||
// Install a requirement, to populate the cache.
|
||||
context
|
||||
.pip_sync()
|
||||
.arg("requirements.txt")
|
||||
.assert()
|
||||
.success();
|
||||
|
||||
// When unlocked, `--force` should still take a lock
|
||||
uv_snapshot!(context.filters(), context.prune().arg("--verbose").arg("--force"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
DEBUG uv [VERSION] ([COMMIT] DATE)
|
||||
DEBUG Acquired lock for `[CACHE_DIR]/`
|
||||
Pruning cache at: [CACHE_DIR]/
|
||||
No unused entries found
|
||||
DEBUG Released lock at `[CACHE_DIR]/.lock`
|
||||
");
|
||||
|
||||
// Add a stale directory to the cache.
|
||||
let simple = context.cache_dir.child("simple-v4");
|
||||
simple.create_dir_all()?;
|
||||
|
||||
// When locked, `--force` should proceed without blocking
|
||||
let _cache = uv_cache::Cache::from_path(context.cache_dir.path()).with_exclusive_lock();
|
||||
uv_snapshot!(context.filters(), context.prune().arg("--verbose").arg("--force"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
DEBUG uv [VERSION] ([COMMIT] DATE)
|
||||
DEBUG Lock is busy for `[CACHE_DIR]/`
|
||||
DEBUG Cache is currently in use, proceeding due to `--force`
|
||||
Pruning cache at: [CACHE_DIR]/
|
||||
DEBUG Removing dangling cache bucket: [CACHE_DIR]/simple-v4
|
||||
Removed 1 directory
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `cache prune --ci` should remove all unzipped archives.
|
||||
#[test]
|
||||
fn prune_unzipped() -> Result<()> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue