From 6958c28231fdad2a02f5b263c25fcdeebc9c6ab1 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 11 Jun 2024 15:20:20 -0400 Subject: [PATCH] Make missing METADATA a recoverable error --- Cargo.lock | 1 - crates/uv-client/Cargo.toml | 1 - crates/uv-client/src/error.rs | 11 ------ crates/uv-resolver/src/pubgrub/report.rs | 38 +++++++++++++++++++ .../uv-resolver/src/resolver/availability.rs | 10 +++++ crates/uv-resolver/src/resolver/mod.rs | 14 +++++++ crates/uv-resolver/src/resolver/provider.rs | 5 +++ 7 files changed, 67 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b83f1d9388..5076e0fcb31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4544,7 +4544,6 @@ dependencies = [ "serde", "serde_json", "sys-info", - "tempfile", "thiserror", "tl", "tokio", diff --git a/crates/uv-client/Cargo.toml b/crates/uv-client/Cargo.toml index 85a5fb6e0e0..f4f7bd8bdfa 100644 --- a/crates/uv-client/Cargo.toml +++ b/crates/uv-client/Cargo.toml @@ -38,7 +38,6 @@ rmp-serde = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } sys-info = { workspace = true } -tempfile = { workspace = true } thiserror = { workspace = true } tl = { workspace = true } tokio = { workspace = true } diff --git a/crates/uv-client/src/error.rs b/crates/uv-client/src/error.rs index d332d1eb43b..6d2c2baeac8 100644 --- a/crates/uv-client/src/error.rs +++ b/crates/uv-client/src/error.rs @@ -162,10 +162,6 @@ pub enum ErrorKind { #[error("Metadata file `{0}` was not found in {1}")] MetadataNotFound(WheelFilename, String), - /// The metadata file was not found in the registry. - #[error("File `{0}` was not found in the registry at {1}.")] - FileNotFound(String, #[source] BetterReqwestError), - /// A generic request error happened while making a request. Refer to the /// error message for more details. #[error(transparent)] @@ -185,9 +181,6 @@ pub enum ErrorKind { #[error(transparent)] AsyncHttpRangeReader(#[from] AsyncHttpRangeReaderError), - #[error("Expected a single .dist-info directory in {0}, found {1}")] - InvalidDistInfo(WheelFilename, String), - #[error("{0} is not a valid wheel filename")] WheelFilename(#[source] WheelFilenameError), @@ -212,10 +205,6 @@ pub enum ErrorKind { #[error("Cache serialization failed")] Encode(#[source] rmp_serde::encode::Error), - /// An [`io::Error`] with a filename attached - #[error(transparent)] - Persist(#[from] tempfile::PersistError), - #[error("Missing `Content-Type` header for {0}")] MissingContentType(Url), diff --git a/crates/uv-resolver/src/pubgrub/report.rs b/crates/uv-resolver/src/pubgrub/report.rs index 8784900d63e..aa626ad9746 100644 --- a/crates/uv-resolver/src/pubgrub/report.rs +++ b/crates/uv-resolver/src/pubgrub/report.rs @@ -476,6 +476,11 @@ impl PubGrubReportFormatter<'_> { Some(UnavailablePackage::Offline) => { hints.insert(PubGrubHint::Offline); } + Some(UnavailablePackage::MissingMetadata) => { + hints.insert(PubGrubHint::MissingPackageMetadata { + package: package.clone(), + }); + } Some(UnavailablePackage::InvalidMetadata(reason)) => { hints.insert(PubGrubHint::InvalidPackageMetadata { package: package.clone(), @@ -500,6 +505,12 @@ impl PubGrubReportFormatter<'_> { IncompletePackage::Offline => { hints.insert(PubGrubHint::Offline); } + IncompletePackage::MissingMetadata => { + hints.insert(PubGrubHint::MissingVersionMetadata { + package: package.clone(), + version: version.clone(), + }); + } IncompletePackage::InvalidMetadata(reason) => { hints.insert(PubGrubHint::InvalidVersionMetadata { package: package.clone(), @@ -601,6 +612,8 @@ pub(crate) enum PubGrubHint { NoIndex, /// A package was not found in the registry, but network access was disabled. Offline, + /// Metadata for a package could not be found. + MissingPackageMetadata { package: PubGrubPackage }, /// Metadata for a package could not be parsed. InvalidPackageMetadata { package: PubGrubPackage, @@ -613,6 +626,12 @@ pub(crate) enum PubGrubHint { #[derivative(PartialEq = "ignore", Hash = "ignore")] reason: String, }, + /// Metadata for a package version could not be found. + MissingVersionMetadata { + package: PubGrubPackage, + #[derivative(PartialEq = "ignore", Hash = "ignore")] + version: Version, + }, /// Metadata for a package version could not be parsed. InvalidVersionMetadata { package: PubGrubPackage, @@ -689,6 +708,15 @@ impl std::fmt::Display for PubGrubHint { ":".bold(), ) } + Self::MissingPackageMetadata { package } => { + write!( + f, + "{}{} Metadata for {} could not be found, as the wheel is missing a `METADATA` file", + "hint".bold().cyan(), + ":".bold(), + package.bold() + ) + } Self::InvalidPackageMetadata { package, reason } => { write!( f, @@ -709,6 +737,16 @@ impl std::fmt::Display for PubGrubHint { textwrap::indent(reason, " ") ) } + Self::MissingVersionMetadata { package, version } => { + write!( + f, + "{}{} Metadata for {}=={} could not be found, as the wheel is missing a `METADATA` file", + "hint".bold().cyan(), + ":".bold(), + package.bold(), + version.bold(), + ) + } Self::InvalidVersionMetadata { package, version, diff --git a/crates/uv-resolver/src/resolver/availability.rs b/crates/uv-resolver/src/resolver/availability.rs index 63eaa5056e3..f53fe89fddd 100644 --- a/crates/uv-resolver/src/resolver/availability.rs +++ b/crates/uv-resolver/src/resolver/availability.rs @@ -30,6 +30,8 @@ impl Display for UnavailableReason { pub(crate) enum UnavailableVersion { /// Version is incompatible because it has no usable distributions IncompatibleDist(IncompatibleDist), + /// The wheel metadata was not found. + MissingMetadata, /// The wheel metadata was found, but could not be parsed. InvalidMetadata, /// The wheel metadata was found, but the metadata was inconsistent. @@ -46,6 +48,9 @@ impl Display for UnavailableVersion { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { UnavailableVersion::IncompatibleDist(invalid_dist) => Display::fmt(invalid_dist, f), + UnavailableVersion::MissingMetadata => { + f.write_str("does not include a `METADATA` file") + } UnavailableVersion::InvalidMetadata => f.write_str("has invalid metadata"), UnavailableVersion::InconsistentMetadata => f.write_str("has inconsistent metadata"), UnavailableVersion::InvalidStructure => f.write_str("has an invalid package format"), @@ -66,6 +71,8 @@ pub(crate) enum UnavailablePackage { Offline, /// The package was not found in the registry. NotFound, + /// The package metadata was not found. + MissingMetadata, /// The package metadata was found, but could not be parsed. InvalidMetadata(String), /// The package has an invalid structure. @@ -78,6 +85,7 @@ impl UnavailablePackage { UnavailablePackage::NoIndex => "was not found in the provided package locations", UnavailablePackage::Offline => "was not found in the cache", UnavailablePackage::NotFound => "was not found in the package registry", + UnavailablePackage::MissingMetadata => "does not include a `METADATA` file", UnavailablePackage::InvalidMetadata(_) => "has invalid metadata", UnavailablePackage::InvalidStructure(_) => "has an invalid package format", } @@ -95,6 +103,8 @@ impl Display for UnavailablePackage { pub(crate) enum IncompletePackage { /// Network requests were disabled (i.e., `--offline`), and the wheel metadata was not found in the cache. Offline, + /// The wheel metadata was not found. + MissingMetadata, /// The wheel metadata was found, but could not be parsed. InvalidMetadata(String), /// The wheel metadata was found, but the metadata was inconsistent. diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index 85f23fc1c59..78a455342cf 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -749,6 +749,11 @@ impl ResolverState { + self.unavailable_packages + .insert(name.clone(), UnavailablePackage::MissingMetadata); + return Ok(None); + } MetadataResponse::InvalidMetadata(err) => { self.unavailable_packages.insert( name.clone(), @@ -1042,6 +1047,15 @@ impl ResolverState { + self.incomplete_packages + .entry(name.clone()) + .or_default() + .insert(version.clone(), IncompletePackage::MissingMetadata); + return Ok(Dependencies::Unavailable( + UnavailableVersion::MissingMetadata, + )); + } MetadataResponse::InvalidMetadata(err) => { warn!("Unable to extract metadata for {name}: {err}"); self.incomplete_packages diff --git a/crates/uv-resolver/src/resolver/provider.rs b/crates/uv-resolver/src/resolver/provider.rs index 35e3725dff8..10decd0a4a2 100644 --- a/crates/uv-resolver/src/resolver/provider.rs +++ b/crates/uv-resolver/src/resolver/provider.rs @@ -33,6 +33,8 @@ pub enum VersionsResponse { pub enum MetadataResponse { /// The wheel metadata was found and parsed successfully. Found(ArchiveMetadata), + /// The wheel metadata was not found. + MissingMetadata, /// The wheel metadata was found, but could not be parsed. InvalidMetadata(Box), /// The wheel metadata was found, but the metadata was inconsistent. @@ -184,6 +186,9 @@ impl<'a, Context: BuildContext> ResolverProvider for DefaultResolverProvider<'a, Err(err) => match err { uv_distribution::Error::Client(client) => match client.into_kind() { uv_client::ErrorKind::Offline(_) => Ok(MetadataResponse::Offline), + uv_client::ErrorKind::MetadataNotFound(_, _) => { + Ok(MetadataResponse::MissingMetadata) + } uv_client::ErrorKind::MetadataParseError(_, _, err) => { Ok(MetadataResponse::InvalidMetadata(err)) }