diff --git a/crates/puffin-cli/src/commands/pip_compile.rs b/crates/puffin-cli/src/commands/pip_compile.rs index bea243c57..602626308 100644 --- a/crates/puffin-cli/src/commands/pip_compile.rs +++ b/crates/puffin-cli/src/commands/pip_compile.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, Result}; use colored::Colorize; use fs_err::File; use itertools::Itertools; -use pubgrub::report::Reporter; + use tracing::debug; use pep508_rs::Requirement; @@ -17,7 +17,7 @@ use puffin_client::RegistryClientBuilder; use puffin_dispatch::BuildDispatch; use puffin_interpreter::Virtualenv; use puffin_normalize::ExtraName; -use puffin_resolver::{Manifest, PreReleaseMode, ResolutionFailureReporter, ResolutionMode}; +use puffin_resolver::{Manifest, PreReleaseMode, ResolutionMode}; use std::str::FromStr; use crate::commands::reporters::ResolverReporter; @@ -149,14 +149,11 @@ pub(crate) async fn pip_compile( ) .with_reporter(ResolverReporter::from(printer)); let resolution = match resolver.resolve().await { - Err(puffin_resolver::ResolveError::PubGrub(pubgrub::error::PubGrubError::NoSolution( - derivation_tree, - ))) => { + Err(puffin_resolver::ResolveError::PubGrub(err)) => { #[allow(clippy::print_stderr)] { - let report = - miette::Report::msg(ResolutionFailureReporter::report(&derivation_tree)) - .context("No solution found when resolving dependencies:"); + let report = miette::Report::msg(format!("{err}")) + .context("No solution found when resolving dependencies:"); eprint!("{report:?}"); } return Ok(ExitStatus::Failure); diff --git a/crates/puffin-dispatch/src/lib.rs b/crates/puffin-dispatch/src/lib.rs index 46fc954c7..29e4e265f 100644 --- a/crates/puffin-dispatch/src/lib.rs +++ b/crates/puffin-dispatch/src/lib.rs @@ -85,7 +85,7 @@ impl BuildContext for BuildDispatch { self, ); let resolution_graph = resolver.resolve().await.context( - "No solution found when resolving build dependencies for source distribution build", + "No solution found when resolving build dependencies for source distribution:", )?; Ok(resolution_graph.requirements()) }) diff --git a/crates/puffin-resolver/src/error.rs b/crates/puffin-resolver/src/error.rs index 85eae54c5..272b8e131 100644 --- a/crates/puffin-resolver/src/error.rs +++ b/crates/puffin-resolver/src/error.rs @@ -1,4 +1,7 @@ +use std::fmt::Formatter; + use pubgrub::range::Range; +use pubgrub::report::Reporter; use thiserror::Error; use url::Url; @@ -6,6 +9,7 @@ use pep508_rs::Requirement; use puffin_normalize::PackageName; use crate::pubgrub::{PubGrubPackage, PubGrubVersion}; +use crate::ResolutionFailureReporter; #[derive(Error, Debug)] pub enum ResolveError { @@ -25,7 +29,7 @@ pub enum ResolveError { Join(#[from] tokio::task::JoinError), #[error(transparent)] - PubGrub(#[from] pubgrub::error::PubGrubError>), + PubGrub(#[from] RichPubGrubError), #[error("Package metadata name `{metadata}` does not match given name `{given}`")] NameMismatch { @@ -64,3 +68,28 @@ impl From> for ResolveError { value.into_send_error().into() } } + +/// A wrapper around [`pubgrub::error::PubGrubError`] that displays a resolution failure report. +#[derive(Debug)] +pub struct RichPubGrubError { + source: pubgrub::error::PubGrubError>, +} + +impl std::error::Error for RichPubGrubError {} + +impl std::fmt::Display for RichPubGrubError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if let pubgrub::error::PubGrubError::NoSolution(derivation_tree) = &self.source { + let report = ResolutionFailureReporter::report(derivation_tree); + write!(f, "{report}") + } else { + write!(f, "{}", self.source) + } + } +} + +impl From>> for ResolveError { + fn from(value: pubgrub::error::PubGrubError>) -> Self { + ResolveError::PubGrub(RichPubGrubError { source: value }) + } +} diff --git a/crates/puffin-resolver/tests/snapshots/resolver__black_allow_prerelease_if_necessary.snap b/crates/puffin-resolver/tests/snapshots/resolver__black_allow_prerelease_if_necessary.snap index fee91039f..ee1aaf989 100644 --- a/crates/puffin-resolver/tests/snapshots/resolver__black_allow_prerelease_if_necessary.snap +++ b/crates/puffin-resolver/tests/snapshots/resolver__black_allow_prerelease_if_necessary.snap @@ -2,4 +2,4 @@ source: crates/puffin-resolver/tests/resolver.rs expression: resolution --- -No solution +Because there is no version of black available matching <=20.0 and root depends on black<=20.0, version solving failed. diff --git a/crates/puffin-resolver/tests/snapshots/resolver__black_disallow_prerelease.snap b/crates/puffin-resolver/tests/snapshots/resolver__black_disallow_prerelease.snap index 211085917..a21142714 100644 --- a/crates/puffin-resolver/tests/snapshots/resolver__black_disallow_prerelease.snap +++ b/crates/puffin-resolver/tests/snapshots/resolver__black_disallow_prerelease.snap @@ -2,4 +2,4 @@ source: crates/puffin-resolver/tests/resolver.rs expression: err --- -No solution +Because there is no version of black available matching <=20.0 and root depends on black<=20.0, version solving failed.