Make cache robust to removed archives (#6284)
## Summary Closes https://github.com/astral-sh/uv/issues/6147. ## Test Plan - `cargo run pip install flask --no-binary flask --cache-dir foo --reinstall` - `rm -rf foo/archive-v0` - `cargo run pip install flask --no-binary flask --cache-dir foo --reinstall`
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use distribution_types::Hashed;
|
||||
use pypi_types::HashDigest;
|
||||
use uv_cache::ArchiveId;
|
||||
use uv_cache::{ArchiveId, Cache};
|
||||
|
||||
/// An archive (unzipped wheel) that exists in the local cache.
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
@@ -16,6 +16,11 @@ impl Archive {
|
||||
pub(crate) fn new(id: ArchiveId, hashes: Vec<HashDigest>) -> Self {
|
||||
Self { id, hashes }
|
||||
}
|
||||
|
||||
/// Returns `true` if the archive exists in the cache.
|
||||
pub(crate) fn exists(&self, cache: &Cache) -> bool {
|
||||
cache.archive(&self.id).exists()
|
||||
}
|
||||
}
|
||||
|
||||
impl Hashed for Archive {
|
||||
|
||||
@@ -596,8 +596,12 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
|
||||
CachedClientError::Client(err) => Error::Client(err),
|
||||
})?;
|
||||
|
||||
// If the archive is missing the required hashes, force a refresh.
|
||||
let archive = if archive.has_digests(hashes) {
|
||||
// If the archive is missing the required hashes, or has since been removed, force a refresh.
|
||||
let archive = Some(archive)
|
||||
.filter(|archive| archive.has_digests(hashes))
|
||||
.filter(|archive| archive.exists(self.build_context.cache()));
|
||||
|
||||
let archive = if let Some(archive) = archive {
|
||||
archive
|
||||
} else {
|
||||
self.client
|
||||
@@ -746,12 +750,16 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
|
||||
CachedClientError::Client(err) => Error::Client(err),
|
||||
})?;
|
||||
|
||||
// If the archive is missing the required hashes, force a refresh.
|
||||
let archive = if archive.has_digests(hashes) {
|
||||
// If the archive is missing the required hashes, or has since been removed, force a refresh.
|
||||
let archive = Some(archive)
|
||||
.filter(|archive| archive.has_digests(hashes))
|
||||
.filter(|archive| archive.exists(self.build_context.cache()));
|
||||
|
||||
let archive = if let Some(archive) = archive {
|
||||
archive
|
||||
} else {
|
||||
self.client
|
||||
.managed(|client| async move {
|
||||
.managed(|client| async {
|
||||
client
|
||||
.cached_client()
|
||||
.skip_cache(self.request(url)?, &http_entry, download)
|
||||
|
||||
Reference in New Issue
Block a user