mirror of https://github.com/astral-sh/uv
Remove dangling archives in `uv cache clean ${package}` (#6915)
## Summary Closes https://github.com/astral-sh/uv/issues/6909.
This commit is contained in:
parent
a5f1e1c765
commit
049c73d09e
|
|
@ -322,10 +322,62 @@ impl Cache {
|
|||
///
|
||||
/// Returns the number of entries removed from the cache.
|
||||
pub fn remove(&self, name: &PackageName) -> Result<Removal, io::Error> {
|
||||
// Collect the set of referenced archives.
|
||||
let before = {
|
||||
let mut references = FxHashSet::default();
|
||||
for bucket in CacheBucket::iter() {
|
||||
let bucket = self.bucket(bucket);
|
||||
if bucket.is_dir() {
|
||||
for entry in walkdir::WalkDir::new(bucket) {
|
||||
let entry = entry?;
|
||||
if entry.file_type().is_symlink() {
|
||||
if let Ok(target) = fs_err::canonicalize(entry.path()) {
|
||||
references.insert(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
references
|
||||
};
|
||||
|
||||
// Remove any entries for the package from the cache.
|
||||
let mut summary = Removal::default();
|
||||
for bucket in CacheBucket::iter() {
|
||||
summary += bucket.remove(self, name)?;
|
||||
}
|
||||
|
||||
// Collect the set of referenced archives after the removal.
|
||||
let after = {
|
||||
let mut references = FxHashSet::default();
|
||||
for bucket in CacheBucket::iter() {
|
||||
let bucket = self.bucket(bucket);
|
||||
if bucket.is_dir() {
|
||||
for entry in walkdir::WalkDir::new(bucket) {
|
||||
let entry = entry?;
|
||||
if entry.file_type().is_symlink() {
|
||||
if let Ok(target) = fs_err::canonicalize(entry.path()) {
|
||||
references.insert(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
references
|
||||
};
|
||||
|
||||
if before != after {
|
||||
// Remove any archives that are no longer referenced.
|
||||
for entry in fs::read_dir(self.bucket(CacheBucket::Archive))? {
|
||||
let entry = entry?;
|
||||
let path = fs_err::canonicalize(entry.path())?;
|
||||
if !after.contains(&path) && before.contains(&path) {
|
||||
debug!("Removing dangling cache entry: {}", path.display());
|
||||
summary += rm_rf(path)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(summary)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,14 +65,27 @@ fn clean_package_pypi() -> Result<()> {
|
|||
"Expected the `.rkyv` file to exist for `iniconfig`"
|
||||
);
|
||||
|
||||
uv_snapshot!(context.filters(), context.clean().arg("--verbose").arg("iniconfig"), @r###"
|
||||
let filters: Vec<_> = context
|
||||
.filters()
|
||||
.into_iter()
|
||||
.chain([
|
||||
// The cache entry does not have a stable key, so we filter it out
|
||||
(
|
||||
r"\[CACHE_DIR\](\\|\/)(.+)(\\|\/).*",
|
||||
"[CACHE_DIR]/$2/[ENTRY]",
|
||||
),
|
||||
])
|
||||
.collect();
|
||||
|
||||
uv_snapshot!(&filters, context.clean().arg("--verbose").arg("iniconfig"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
DEBUG uv [VERSION] ([COMMIT] DATE)
|
||||
Removed 4 files for iniconfig ([SIZE])
|
||||
DEBUG Removing dangling cache entry: [CACHE_DIR]/archive-v0/[ENTRY]
|
||||
Removed 13 files for iniconfig ([SIZE])
|
||||
"###);
|
||||
|
||||
// Assert that the `.rkyv` file is removed for `iniconfig`.
|
||||
|
|
@ -81,6 +94,18 @@ fn clean_package_pypi() -> Result<()> {
|
|||
"Expected the `.rkyv` file to be removed for `iniconfig`"
|
||||
);
|
||||
|
||||
// Running `uv cache prune` should have no effect.
|
||||
uv_snapshot!(&filters, context.prune().arg("--verbose"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
DEBUG uv [VERSION] ([COMMIT] DATE)
|
||||
Pruning cache at: [CACHE_DIR]/
|
||||
No unused entries found
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -113,14 +138,27 @@ fn clean_package_index() -> Result<()> {
|
|||
"Expected the `.rkyv` file to exist for `iniconfig`"
|
||||
);
|
||||
|
||||
uv_snapshot!(context.filters(), context.clean().arg("--verbose").arg("iniconfig"), @r###"
|
||||
let filters: Vec<_> = context
|
||||
.filters()
|
||||
.into_iter()
|
||||
.chain([
|
||||
// The cache entry does not have a stable key, so we filter it out
|
||||
(
|
||||
r"\[CACHE_DIR\](\\|\/)(.+)(\\|\/).*",
|
||||
"[CACHE_DIR]/$2/[ENTRY]",
|
||||
),
|
||||
])
|
||||
.collect();
|
||||
|
||||
uv_snapshot!(&filters, context.clean().arg("--verbose").arg("iniconfig"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
DEBUG uv [VERSION] ([COMMIT] DATE)
|
||||
Removed 4 files for iniconfig ([SIZE])
|
||||
DEBUG Removing dangling cache entry: [CACHE_DIR]/archive-v0/[ENTRY]
|
||||
Removed 13 files for iniconfig ([SIZE])
|
||||
"###);
|
||||
|
||||
// Assert that the `.rkyv` file is removed for `iniconfig`.
|
||||
|
|
|
|||
|
|
@ -1396,7 +1396,7 @@ fn install_url_source_dist_cached() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Removed 13 files for source-distribution ([SIZE])
|
||||
Removed 19 files for source-distribution ([SIZE])
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -1591,7 +1591,7 @@ fn install_registry_source_dist_cached() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Removed 14 files for source-distribution ([SIZE])
|
||||
Removed 20 files for source-distribution ([SIZE])
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -1687,7 +1687,7 @@ fn install_path_source_dist_cached() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Removed 13 files for source-distribution ([SIZE])
|
||||
Removed 19 files for source-distribution ([SIZE])
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -1788,7 +1788,7 @@ fn install_path_built_dist_cached() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Removed 2 files for tomli ([SIZE])
|
||||
Removed 11 files for tomli ([SIZE])
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
@ -1876,7 +1876,7 @@ fn install_url_built_dist_cached() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Removed 3 files for tqdm ([SIZE])
|
||||
Removed 43 files for tqdm ([SIZE])
|
||||
"###
|
||||
);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue