Heal cache entries with missing source distributions (#7559)

## Summary

`uv cache prune --ci` will remove the source distribution directory. If
we then need to build a _different_ wheel (e.g., you're building a
package that has Python minor version-specific wheels), we fail, because
we expect the source to be there.

Now, if the source is missing, we re-download it. It would be slightly
easier to just _ignore_ that revision, but that would mean we'd also
lose the already-built wheels -- so if you ran against many Python
versions, we'd continuously lose the cached data.

Closes https://github.com/astral-sh/uv/issues/7543.

## Test Plan

We can add tests, but they _need_ to build non-pure Python wheels, which
tends to be expensive...

For reference:

```console
$ cargo run venv --python 3.12
$ cargo run pip install mercurial==6.8.1 --verbose
$ cargo run cache prune --ci
$ cargo run venv --python 3.11
$ cargo run pip install mercurial==6.8.1 --verbose
```

I also did this with a local `.tar.gz` that I downloaded from PyPI.
This commit is contained in:
Charlie Marsh 2024-09-19 16:31:55 -04:00 committed by GitHub
parent 5de6d2338d
commit f3463b3d08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 138 additions and 10 deletions

View file

@ -1,5 +1,6 @@
use std::path::PathBuf;
use owo_colors::OwoColorize;
use tokio::task::JoinError;
use url::Url;
use zip::result::ZipError;
@ -93,6 +94,8 @@ pub enum Error {
MetadataLowering(#[from] MetadataError),
#[error("Distribution not found at: {0}")]
NotFound(Url),
#[error("Attempted to re-extract the source distribution for `{0}`, but the hashes didn't match. Run `{}` to clear the cache.", "uv cache clean".green())]
CacheHeal(String),
/// A generic request middleware error happened while making a request.
/// Refer to the error message for more details.