mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-03 05:03:46 +00:00
Use generic pubgrub incompatibility reason (#3335)
Pubgrub got a new feature where all unavailability is a custom, instead of the reasonless `UnavailableDependencies` and our custom `String` type previously (https://github.com/pubgrub-rs/pubgrub/pull/208). This PR introduces a `UnavailableReason` that tracks either an entire version being unusable, or a specific version. The error messages now also track this difference properly. The pubgrub commit is our main rebased onto the merged https://github.com/pubgrub-rs/pubgrub/pull/208, i'll push `konsti/main-rebase-generic-reason` to `main` after checking for rebase problems.
This commit is contained in:
parent
bd7860de17
commit
1ad6aa8a23
11 changed files with 215 additions and 165 deletions
|
|
@ -6,6 +6,7 @@ use pubgrub::solver::{Dependencies, DependencyProvider};
|
|||
use pep440_rs::Version;
|
||||
|
||||
use crate::pubgrub::{PubGrubPackage, PubGrubPriority};
|
||||
use crate::resolver::UnavailableReason;
|
||||
|
||||
/// We don't use a dependency provider, we interact with state directly, but we still need this one
|
||||
/// for type
|
||||
|
|
@ -15,6 +16,8 @@ impl DependencyProvider for UvDependencyProvider {
|
|||
type P = PubGrubPackage;
|
||||
type V = Version;
|
||||
type VS = Range<Version>;
|
||||
type M = UnavailableReason;
|
||||
|
||||
fn prioritize(&self, _package: &Self::P, _range: &Self::VS) -> Self::Priority {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
@ -34,7 +37,7 @@ impl DependencyProvider for UvDependencyProvider {
|
|||
&self,
|
||||
_package: &Self::P,
|
||||
_version: &Self::V,
|
||||
) -> Result<Dependencies<Vec<(Self::P, Self::VS)>>, Self::Err> {
|
||||
) -> Result<Dependencies<Vec<(Self::P, Self::VS)>, Self::M>, Self::Err> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ use crate::dependency_provider::UvDependencyProvider;
|
|||
use crate::pubgrub::{PubGrubPackage, PubGrubPython, PubGrubReportFormatter};
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::resolver::{
|
||||
IncompletePackage, SharedMap, SharedSet, UnavailablePackage, VersionsResponse,
|
||||
IncompletePackage, SharedMap, SharedSet, UnavailablePackage, UnavailableReason,
|
||||
VersionsResponse,
|
||||
};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
|
|
@ -119,7 +120,9 @@ impl<T> From<tokio::sync::mpsc::error::SendError<T>> for ResolveError {
|
|||
|
||||
/// Given a [`DerivationTree`], collapse any [`External::FromDependencyOf`] incompatibilities
|
||||
/// wrap an [`PubGrubPackage::Extra`] package.
|
||||
fn collapse_extra_proxies(derivation_tree: &mut DerivationTree<PubGrubPackage, Range<Version>>) {
|
||||
fn collapse_extra_proxies(
|
||||
derivation_tree: &mut DerivationTree<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
) {
|
||||
match derivation_tree {
|
||||
DerivationTree::External(_) => {}
|
||||
DerivationTree::Derived(derived) => {
|
||||
|
|
@ -193,7 +196,7 @@ impl From<pubgrub::error::PubGrubError<UvDependencyProvider>> for ResolveError {
|
|||
/// A wrapper around [`pubgrub::error::PubGrubError::NoSolution`] that displays a resolution failure report.
|
||||
#[derive(Debug)]
|
||||
pub struct NoSolutionError {
|
||||
derivation_tree: DerivationTree<PubGrubPackage, Range<Version>>,
|
||||
derivation_tree: DerivationTree<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
available_versions: IndexMap<PubGrubPackage, BTreeSet<Version>>,
|
||||
selector: Option<CandidateSelector>,
|
||||
python_requirement: Option<PythonRequirement>,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use uv_normalize::PackageName;
|
|||
|
||||
use crate::candidate_selector::CandidateSelector;
|
||||
use crate::python_requirement::PythonRequirement;
|
||||
use crate::resolver::{IncompletePackage, UnavailablePackage};
|
||||
use crate::resolver::{IncompletePackage, UnavailablePackage, UnavailableReason};
|
||||
|
||||
use super::PubGrubPackage;
|
||||
|
||||
|
|
@ -30,15 +30,20 @@ pub(crate) struct PubGrubReportFormatter<'a> {
|
|||
pub(crate) python_requirement: Option<&'a PythonRequirement>,
|
||||
}
|
||||
|
||||
impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<'_> {
|
||||
impl ReportFormatter<PubGrubPackage, Range<Version>, UnavailableReason>
|
||||
for PubGrubReportFormatter<'_>
|
||||
{
|
||||
type Output = String;
|
||||
|
||||
fn format_external(&self, external: &External<PubGrubPackage, Range<Version>>) -> Self::Output {
|
||||
fn format_external(
|
||||
&self,
|
||||
external: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
) -> Self::Output {
|
||||
match external {
|
||||
External::NotRoot(package, version) => {
|
||||
format!("we are solving dependencies of {package} {version}")
|
||||
}
|
||||
External::NoVersions(package, set, reason) => {
|
||||
External::NoVersions(package, set) => {
|
||||
if matches!(package, PubGrubPackage::Python(_)) {
|
||||
if let Some(python) = self.python_requirement {
|
||||
if python.target() == python.installed() {
|
||||
|
|
@ -79,16 +84,6 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
}
|
||||
let set = self.simplify_set(set, package);
|
||||
|
||||
// Check for a reason
|
||||
if let Some(reason) = reason {
|
||||
let formatted = if set.as_ref() == &Range::full() {
|
||||
format!("{package} {reason}")
|
||||
} else {
|
||||
format!("{package}{set} {reason}")
|
||||
};
|
||||
return formatted;
|
||||
}
|
||||
|
||||
if set.as_ref() == &Range::full() {
|
||||
format!("there are no versions of {package}")
|
||||
} else if set.as_singleton().is_some() {
|
||||
|
|
@ -112,17 +107,26 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
}
|
||||
}
|
||||
}
|
||||
External::Unavailable(package, set, reason) => match package {
|
||||
External::Custom(package, set, reason) => match package {
|
||||
PubGrubPackage::Root(Some(name)) => {
|
||||
format!("{name} cannot be used because {reason}")
|
||||
}
|
||||
PubGrubPackage::Root(None) => {
|
||||
format!("your requirements cannot be used because {reason}")
|
||||
}
|
||||
_ => format!(
|
||||
"{}is unusable because {reason}",
|
||||
Padded::new("", &PackageRange::compatibility(package, set), " ")
|
||||
),
|
||||
_ => match reason {
|
||||
UnavailableReason::Package(reason) => {
|
||||
// While there may be a term attached, this error applies to the entire
|
||||
// package, so we show it for the entire package
|
||||
format!("{}{reason}", Padded::new("", &package, " "))
|
||||
}
|
||||
UnavailableReason::Version(reason) => {
|
||||
format!(
|
||||
"{}{reason}",
|
||||
Padded::new("", &PackageRange::compatibility(package, set), " ")
|
||||
)
|
||||
}
|
||||
},
|
||||
},
|
||||
External::FromDependencyOf(package, package_set, dependency, dependency_set) => {
|
||||
let package_set = self.simplify_set(package_set, package);
|
||||
|
|
@ -198,8 +202,8 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
/// Simplest case, we just combine two external incompatibilities.
|
||||
fn explain_both_external(
|
||||
&self,
|
||||
external1: &External<PubGrubPackage, Range<Version>>,
|
||||
external2: &External<PubGrubPackage, Range<Version>>,
|
||||
external1: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
external2: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let external = self.format_both_external(external1, external2);
|
||||
|
|
@ -216,9 +220,9 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
fn explain_both_ref(
|
||||
&self,
|
||||
ref_id1: usize,
|
||||
derived1: &Derived<PubGrubPackage, Range<Version>>,
|
||||
derived1: &Derived<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
ref_id2: usize,
|
||||
derived2: &Derived<PubGrubPackage, Range<Version>>,
|
||||
derived2: &Derived<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
// TODO: order should be chosen to make it more logical.
|
||||
|
|
@ -243,8 +247,8 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
fn explain_ref_and_external(
|
||||
&self,
|
||||
ref_id: usize,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>>,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
external: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
// TODO: order should be chosen to make it more logical.
|
||||
|
|
@ -265,7 +269,7 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
/// Add an external cause to the chain of explanations.
|
||||
fn and_explain_external(
|
||||
&self,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
external: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let external = self.format_external(external);
|
||||
|
|
@ -282,7 +286,7 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
fn and_explain_ref(
|
||||
&self,
|
||||
ref_id: usize,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>>,
|
||||
derived: &Derived<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let derived = self.format_terms(&derived.terms);
|
||||
|
|
@ -299,8 +303,8 @@ impl ReportFormatter<PubGrubPackage, Range<Version>> for PubGrubReportFormatter<
|
|||
/// Add an already explained incompat to the chain of explanations.
|
||||
fn and_explain_prior_and_external(
|
||||
&self,
|
||||
prior_external: &External<PubGrubPackage, Range<Version>>,
|
||||
external: &External<PubGrubPackage, Range<Version>>,
|
||||
prior_external: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
external: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
current_terms: &Map<PubGrubPackage, Term<Range<Version>>>,
|
||||
) -> String {
|
||||
let external = self.format_both_external(prior_external, external);
|
||||
|
|
@ -318,8 +322,8 @@ impl PubGrubReportFormatter<'_> {
|
|||
/// Format two external incompatibilities, combining them if possible.
|
||||
fn format_both_external(
|
||||
&self,
|
||||
external1: &External<PubGrubPackage, Range<Version>>,
|
||||
external2: &External<PubGrubPackage, Range<Version>>,
|
||||
external1: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
external2: &External<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
) -> String {
|
||||
match (external1, external2) {
|
||||
(
|
||||
|
|
@ -387,7 +391,7 @@ impl PubGrubReportFormatter<'_> {
|
|||
/// their requirements.
|
||||
pub(crate) fn hints(
|
||||
&self,
|
||||
derivation_tree: &DerivationTree<PubGrubPackage, Range<Version>>,
|
||||
derivation_tree: &DerivationTree<PubGrubPackage, Range<Version>, UnavailableReason>,
|
||||
selector: &Option<CandidateSelector>,
|
||||
index_locations: &Option<IndexLocations>,
|
||||
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
|
||||
|
|
@ -404,7 +408,7 @@ impl PubGrubReportFormatter<'_> {
|
|||
let mut hints = IndexSet::default();
|
||||
match derivation_tree {
|
||||
DerivationTree::External(external) => match external {
|
||||
External::Unavailable(package, set, _) | External::NoVersions(package, set, _) => {
|
||||
External::Custom(package, set, _) | External::NoVersions(package, set) => {
|
||||
// Check for no versions due to pre-release options
|
||||
if let Some(selector) = selector {
|
||||
let any_prerelease = set.iter().any(|(start, end)| {
|
||||
|
|
|
|||
|
|
@ -66,16 +66,62 @@ mod provider;
|
|||
mod reporter;
|
||||
mod urls;
|
||||
|
||||
/// The package version is unavailable and cannot be used
|
||||
/// Unlike [`PackageUnavailable`] this applies to a single version of the package
|
||||
#[derive(Debug, Clone)]
|
||||
/// The reason why a package or a version cannot be used.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum UnavailableReason {
|
||||
/// The entire package cannot be used.
|
||||
Package(UnavailablePackage),
|
||||
/// A single version cannot be used.
|
||||
Version(UnavailableVersion),
|
||||
}
|
||||
|
||||
impl Display for UnavailableReason {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Version(version) => Display::fmt(version, f),
|
||||
Self::Package(package) => Display::fmt(package, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The package version is unavailable and cannot be used. Unlike [`PackageUnavailable`], this
|
||||
/// applies to a single version of the package.
|
||||
///
|
||||
/// Most variant are from [`MetadataResponse`] without the error source (since we don't format
|
||||
/// the source).
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum UnavailableVersion {
|
||||
/// Version is incompatible because it has no usable distributions
|
||||
IncompatibleDist(IncompatibleDist),
|
||||
/// The wheel metadata was found, but could not be parsed.
|
||||
InvalidMetadata,
|
||||
/// The wheel metadata was found, but the metadata was inconsistent.
|
||||
InconsistentMetadata,
|
||||
/// The wheel has an invalid structure.
|
||||
InvalidStructure,
|
||||
/// The wheel metadata was not found in the cache and the network is not available.
|
||||
Offline,
|
||||
/// Forward any kind of resolver error.
|
||||
ResolverError(String),
|
||||
}
|
||||
|
||||
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::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"),
|
||||
UnavailableVersion::Offline => f.write_str(
|
||||
"network connectivity is disabled, but the metadata wasn't found in the cache",
|
||||
),
|
||||
UnavailableVersion::ResolverError(err) => f.write_str(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The package is unavailable and cannot be used.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub(crate) enum UnavailablePackage {
|
||||
/// Index lookups were disabled (i.e., `--no-index`) and the package was not found in a flat index (i.e. from `--find-links`).
|
||||
NoIndex,
|
||||
|
|
@ -89,6 +135,24 @@ pub(crate) enum UnavailablePackage {
|
|||
InvalidStructure(String),
|
||||
}
|
||||
|
||||
impl UnavailablePackage {
|
||||
pub(crate) fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
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::InvalidMetadata(_) => "has invalid metadata",
|
||||
UnavailablePackage::InvalidStructure(_) => "has an invalid package format",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for UnavailablePackage {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
/// The package is unavailable at specific versions.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum IncompletePackage {
|
||||
|
|
@ -359,84 +423,61 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
.term_intersection_for_package(&next)
|
||||
.expect("a package was chosen but we don't have a term.");
|
||||
|
||||
let reason = {
|
||||
if let PubGrubPackage::Package(ref package_name, _, _) = next {
|
||||
// Check if the decision was due to the package being unavailable
|
||||
self.unavailable_packages
|
||||
.borrow()
|
||||
.get(package_name)
|
||||
.map(|entry| match *entry {
|
||||
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::InvalidMetadata(_) => {
|
||||
"was found, but the metadata could not be parsed"
|
||||
}
|
||||
UnavailablePackage::InvalidStructure(_) => {
|
||||
"was found, but has an invalid format"
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
// Check if the decision was due to the package being unavailable
|
||||
if let PubGrubPackage::Package(ref package_name, _, _) = next {
|
||||
if let Some(entry) = self.unavailable_packages.borrow().get(package_name) {
|
||||
state.add_incompatibility(Incompatibility::custom_term(
|
||||
next.clone(),
|
||||
term_intersection.clone(),
|
||||
UnavailableReason::Package(entry.clone()),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let inc = Incompatibility::no_versions(
|
||||
state.add_incompatibility(Incompatibility::no_versions(
|
||||
next.clone(),
|
||||
term_intersection.clone(),
|
||||
reason.map(ToString::to_string),
|
||||
);
|
||||
|
||||
state.add_incompatibility(inc);
|
||||
));
|
||||
continue;
|
||||
}
|
||||
Some(version) => version,
|
||||
};
|
||||
let version = match version {
|
||||
ResolverVersion::Available(version) => version,
|
||||
ResolverVersion::Unavailable(version, unavailable) => {
|
||||
let reason = match unavailable {
|
||||
// Incompatible requires-python versions are special in that we track
|
||||
// them as incompatible dependencies instead of marking the package version
|
||||
// as unavailable directly
|
||||
UnavailableVersion::IncompatibleDist(
|
||||
IncompatibleDist::Source(IncompatibleSource::RequiresPython(
|
||||
requires_python,
|
||||
))
|
||||
| IncompatibleDist::Wheel(IncompatibleWheel::RequiresPython(
|
||||
requires_python,
|
||||
)),
|
||||
) => {
|
||||
let python_version = requires_python
|
||||
.iter()
|
||||
.map(PubGrubSpecifier::try_from)
|
||||
.fold_ok(Range::full(), |range, specifier| {
|
||||
range.intersection(&specifier.into())
|
||||
})?;
|
||||
ResolverVersion::Unavailable(version, reason) => {
|
||||
// Incompatible requires-python versions are special in that we track
|
||||
// them as incompatible dependencies instead of marking the package version
|
||||
// as unavailable directly
|
||||
if let UnavailableVersion::IncompatibleDist(
|
||||
IncompatibleDist::Source(IncompatibleSource::RequiresPython(
|
||||
requires_python,
|
||||
))
|
||||
| IncompatibleDist::Wheel(IncompatibleWheel::RequiresPython(requires_python)),
|
||||
) = reason
|
||||
{
|
||||
let python_version = requires_python
|
||||
.iter()
|
||||
.map(PubGrubSpecifier::try_from)
|
||||
.fold_ok(Range::full(), |range, specifier| {
|
||||
range.intersection(&specifier.into())
|
||||
})?;
|
||||
|
||||
let package = &next;
|
||||
for kind in [PubGrubPython::Installed, PubGrubPython::Target] {
|
||||
state.add_incompatibility(Incompatibility::from_dependency(
|
||||
package.clone(),
|
||||
Range::singleton(version.clone()),
|
||||
(PubGrubPackage::Python(kind), python_version.clone()),
|
||||
));
|
||||
}
|
||||
state.partial_solution.add_decision(next.clone(), version);
|
||||
continue;
|
||||
}
|
||||
UnavailableVersion::IncompatibleDist(incompatibility) => {
|
||||
incompatibility.to_string()
|
||||
let package = &next;
|
||||
for kind in [PubGrubPython::Installed, PubGrubPython::Target] {
|
||||
state.add_incompatibility(Incompatibility::from_dependency(
|
||||
package.clone(),
|
||||
Range::singleton(version.clone()),
|
||||
(PubGrubPackage::Python(kind), python_version.clone()),
|
||||
));
|
||||
}
|
||||
state.partial_solution.add_decision(next.clone(), version);
|
||||
continue;
|
||||
};
|
||||
state.add_incompatibility(Incompatibility::unavailable(
|
||||
state.add_incompatibility(Incompatibility::custom_version(
|
||||
next.clone(),
|
||||
version.clone(),
|
||||
reason,
|
||||
UnavailableReason::Version(reason),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -467,10 +508,10 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
.await?
|
||||
{
|
||||
Dependencies::Unavailable(reason) => {
|
||||
state.add_incompatibility(Incompatibility::unavailable(
|
||||
state.add_incompatibility(Incompatibility::custom_version(
|
||||
package.clone(),
|
||||
version.clone(),
|
||||
reason.clone(),
|
||||
UnavailableReason::Version(reason),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
|
|
@ -816,7 +857,9 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
let mut constraints = match constraints {
|
||||
Ok(constraints) => constraints,
|
||||
Err(err) => {
|
||||
return Ok(Dependencies::Unavailable(uncapitalize(err.to_string())));
|
||||
return Ok(Dependencies::Unavailable(
|
||||
UnavailableVersion::ResolverError(uncapitalize(err.to_string())),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -939,9 +982,9 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
false,
|
||||
"Dependencies were requested for a package that is not available"
|
||||
);
|
||||
return Ok(Dependencies::Unavailable(
|
||||
"The package is unavailable".to_string(),
|
||||
));
|
||||
return Err(ResolveError::Failure(format!(
|
||||
"The package is unavailable: {package_name}"
|
||||
)));
|
||||
}
|
||||
|
||||
// Wait for the metadata to be available.
|
||||
|
|
@ -962,10 +1005,7 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
.or_default()
|
||||
.borrow_mut()
|
||||
.insert(version.clone(), IncompletePackage::Offline);
|
||||
return Ok(Dependencies::Unavailable(
|
||||
"network connectivity is disabled, but the metadata wasn't found in the cache"
|
||||
.to_string(),
|
||||
));
|
||||
return Ok(Dependencies::Unavailable(UnavailableVersion::Offline));
|
||||
}
|
||||
MetadataResponse::InvalidMetadata(err) => {
|
||||
warn!("Unable to extract metadata for {package_name}: {err}");
|
||||
|
|
@ -979,7 +1019,7 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
IncompletePackage::InvalidMetadata(err.to_string()),
|
||||
);
|
||||
return Ok(Dependencies::Unavailable(
|
||||
"the package metadata could not be parsed".to_string(),
|
||||
UnavailableVersion::InvalidMetadata,
|
||||
));
|
||||
}
|
||||
MetadataResponse::InconsistentMetadata(err) => {
|
||||
|
|
@ -994,7 +1034,7 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
IncompletePackage::InconsistentMetadata(err.to_string()),
|
||||
);
|
||||
return Ok(Dependencies::Unavailable(
|
||||
"the package metadata was inconsistent".to_string(),
|
||||
UnavailableVersion::InconsistentMetadata,
|
||||
));
|
||||
}
|
||||
MetadataResponse::InvalidStructure(err) => {
|
||||
|
|
@ -1009,7 +1049,7 @@ impl<'a, Provider: ResolverProvider, InstalledPackages: InstalledPackagesProvide
|
|||
IncompletePackage::InvalidStructure(err.to_string()),
|
||||
);
|
||||
return Ok(Dependencies::Unavailable(
|
||||
"the package has an invalid format".to_string(),
|
||||
UnavailableVersion::InvalidStructure,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
|
@ -1342,7 +1382,7 @@ enum Response {
|
|||
#[derive(Clone)]
|
||||
enum Dependencies {
|
||||
/// Package dependencies are not available.
|
||||
Unavailable(String),
|
||||
Unavailable(UnavailableVersion),
|
||||
/// Container for all available package versions.
|
||||
Available(Vec<(PubGrubPackage, Range<Version>)>),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue