Surface error when unable to find package (#45)

This commit is contained in:
Charlie Marsh 2023-10-07 15:43:12 -04:00 committed by GitHub
parent 9be02d1590
commit 92160e37df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 11 deletions

1
Cargo.lock generated
View file

@ -1773,6 +1773,7 @@ dependencies = [
"platform-tags", "platform-tags",
"puffin-client", "puffin-client",
"puffin-package", "puffin-package",
"thiserror",
"tracing", "tracing",
"wheel-filename", "wheel-filename",
] ]

View file

@ -49,7 +49,7 @@ pub(crate) async fn compile(src: &Path, cache: Option<&Path>) -> Result<ExitStat
markers, markers,
&tags, &tags,
&client, &client,
puffin_resolver::Flags::default(), puffin_resolver::ResolveFlags::default(),
) )
.await?; .await?;

View file

@ -82,7 +82,7 @@ pub(crate) async fn sync(src: &Path, cache: Option<&Path>, flags: SyncFlags) ->
markers, markers,
&tags, &tags,
&client, &client,
puffin_resolver::Flags::NO_DEPS, puffin_resolver::ResolveFlags::NO_DEPS,
) )
.await?; .await?;

View file

@ -95,10 +95,7 @@ async fn main() -> ExitCode {
Err(err) => { Err(err) => {
#[allow(clippy::print_stderr)] #[allow(clippy::print_stderr)]
{ {
eprintln!("{}", "puffin failed".red().bold()); eprintln!("{}: {}", "error".red().bold(), err);
for cause in err.chain() {
eprintln!(" {} {cause}", "Cause:".bold());
}
} }
ExitStatus::Error.into() ExitStatus::Error.into()
} }

View file

@ -1,5 +1,6 @@
pub use api::{File, SimpleJson}; pub use api::{File, SimpleJson};
pub use client::{PypiClient, PypiClientBuilder}; pub use client::{PypiClient, PypiClientBuilder};
pub use error::PypiClientError;
mod api; mod api;
mod client; mod client;

View file

@ -21,4 +21,5 @@ bitflags = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
pep440_rs = { path = "../pep440-rs" } pep440_rs = { path = "../pep440-rs" }
pep508_rs = { path = "../pep508-rs" } pep508_rs = { path = "../pep508-rs" }
thiserror = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }

View file

@ -5,6 +5,7 @@ use anyhow::Result;
use bitflags::bitflags; use bitflags::bitflags;
use futures::future::Either; use futures::future::Either;
use futures::{StreamExt, TryFutureExt}; use futures::{StreamExt, TryFutureExt};
use thiserror::Error;
use tracing::debug; use tracing::debug;
use pep440_rs::Version; use pep440_rs::Version;
@ -45,20 +46,38 @@ impl PinnedPackage {
bitflags! { bitflags! {
#[derive(Debug, Copy, Clone, Default)] #[derive(Debug, Copy, Clone, Default)]
pub struct Flags: u8 { pub struct ResolveFlags: u8 {
/// Don't install package dependencies. /// Don't install package dependencies.
const NO_DEPS = 1 << 0; const NO_DEPS = 1 << 0;
} }
} }
#[derive(Error, Debug)]
pub enum ResolveError {
#[error("Failed to find a version of {0} that satisfies the requirement")]
NotFound(Requirement),
#[error(transparent)]
Client(#[from] puffin_client::PypiClientError),
#[error(transparent)]
TrySend(#[from] futures::channel::mpsc::SendError),
}
impl<T> From<futures::channel::mpsc::TrySendError<T>> for ResolveError {
fn from(value: futures::channel::mpsc::TrySendError<T>) -> Self {
value.into_send_error().into()
}
}
/// Resolve a set of requirements into a set of pinned versions. /// Resolve a set of requirements into a set of pinned versions.
pub async fn resolve( pub async fn resolve(
requirements: &Requirements, requirements: &Requirements,
markers: &MarkerEnvironment, markers: &MarkerEnvironment,
tags: &Tags, tags: &Tags,
client: &PypiClient, client: &PypiClient,
flags: Flags, flags: ResolveFlags,
) -> Result<Resolution> { ) -> Result<Resolution, ResolveError> {
// A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version // A channel to fetch package metadata (e.g., given `flask`, fetch all versions) and version
// metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version). // metadata (e.g., given `flask==1.0.0`, fetch the metadata for that version).
let (package_sink, package_stream) = futures::channel::mpsc::unbounded(); let (package_sink, package_stream) = futures::channel::mpsc::unbounded();
@ -128,7 +147,7 @@ pub async fn resolve(
.iter() .iter()
.all(|specifier| specifier.contains(&version)) .all(|specifier| specifier.contains(&version))
}) else { }) else {
continue; return Err(ResolveError::NotFound(requirement));
}; };
package_sink.unbounded_send(Request::Version(requirement, file.clone()))?; package_sink.unbounded_send(Request::Version(requirement, file.clone()))?;
@ -151,7 +170,7 @@ pub async fn resolve(
}, },
); );
if !flags.intersects(Flags::NO_DEPS) { if !flags.intersects(ResolveFlags::NO_DEPS) {
// Enqueue its dependencies. // Enqueue its dependencies.
for dependency in metadata.requires_dist { for dependency in metadata.requires_dist {
if !dependency.evaluate_markers( if !dependency.evaluate_markers(