Skip to content

Commit

Permalink
Add an UnusableDependencies incompatibility kind (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
zanieb authored and konstin committed Mar 22, 2024
1 parent 0e08815 commit 073823f
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
7 changes: 7 additions & 0 deletions examples/unsat_root_message_no_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ impl ReportFormatter<Package, Range<SemanticVersion>> for CustomReportFormatter
format!("{package} {package_set} depends on {dependency} {dependency_set}")
}
}
External::UnusableDependencies(package, set, ..) => {
if set == &Range::full() {
format!("dependencies of {package} are unusable")
} else {
format!("dependencies of {package} at version {set} are unusable")
}
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/internal/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct State<DP: DependencyProvider> {
root_package: DP::P,
root_version: DP::V,

/// All incompatibilities indexed by package.
/// The set of incompatibilities for each package.
#[allow(clippy::type_complexity)]
incompatibilities: Map<DP::P, Vec<IncompDpId<DP>>>,

Expand Down
23 changes: 19 additions & 4 deletions src/internal/incompatibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ use crate::version_set::VersionSet;
#[derive(Debug, Clone)]
pub struct Incompatibility<P: Package, VS: VersionSet> {
package_terms: SmallMap<P, Term<VS>>,
/// The reason for the incompatibility.
/// The reason why this version or combination of versions can't be selected.
pub kind: Kind<P, VS>,
}

/// Type alias of unique identifiers for incompatibilities.
pub type IncompId<P, VS> = Id<Incompatibility<P, VS>>;

/// The reason for the incompatibility.
/// The reason why a version or combination of versions can't be selected.
#[derive(Debug, Clone)]
pub enum Kind<P: Package, VS: VersionSet> {
/// Initial incompatibility aiming at picking the root package for the first decision.
Expand All @@ -50,6 +50,8 @@ pub enum Kind<P: Package, VS: VersionSet> {
NoVersions(P, VS),
/// Dependencies of the package are unavailable for versions in that range.
UnavailableDependencies(P, VS),
/// Dependencies of the package are unusable for versions in that range.
UnusableDependencies(P, VS, Option<String>),
/// Incompatibility coming from the dependencies of a given package.
FromDependencyOf(P, VS, P, VS),
/// Derived from two causes. Stores cause ids.
Expand Down Expand Up @@ -109,6 +111,17 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
}
}

/// Create an incompatibility to remember
/// that a package version is not selectable
/// because its dependencies are not usable.
pub fn unusable_dependencies(package: P, version: VS::V, reason: Option<String>) -> Self {
let set = VS::singleton(version);
Self {
package_terms: SmallMap::One([(package.clone(), Term::Positive(set.clone()))]),
kind: Kind::UnusableDependencies(package, set, reason),
}
}

/// Build an incompatibility from a given dependency.
pub fn from_dependency(package: P, versions: VS, dep: (&P, &VS)) -> Self {
let (p2, set2) = dep;
Expand All @@ -125,8 +138,7 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
}
}

/// Return the two packages where this incompatibility when the incompatibility was created
/// through a dependency edge between the two.
/// The two packages causing the incompatibility, if it was derived from dependencies.
pub fn as_dependency(&self) -> Option<(&P, &P)> {
match &self.kind {
Kind::FromDependencyOf(p1, _, p2, _) => Some((p1, p2)),
Expand Down Expand Up @@ -262,6 +274,9 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
Kind::UnavailableDependencies(package, set) => {
DerivationTree::External(External::UnavailableDependencies(package, set))
}
Kind::UnusableDependencies(package, set, reason) => {
DerivationTree::External(External::UnusableDependencies(package, set, reason))
}
Kind::FromDependencyOf(package, set, dep_package, dep_set) => DerivationTree::External(
External::FromDependencyOf(package, set, dep_package, dep_set),
),
Expand Down
32 changes: 32 additions & 0 deletions src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum External<P: Package, VS: VersionSet> {
NoVersions(P, VS),
/// Dependencies of the package are unavailable for versions in that set.
UnavailableDependencies(P, VS),
/// Dependencies of the package are unusable for versions in that set.
UnusableDependencies(P, VS, Option<String>),
/// Incompatibility coming from the dependencies of a given package.
FromDependencyOf(P, VS, P, VS),
}
Expand Down Expand Up @@ -124,6 +126,13 @@ impl<P: Package, VS: VersionSet> DerivationTree<P, VS> {
DerivationTree::External(External::UnavailableDependencies(_, r)) => Some(
DerivationTree::External(External::UnavailableDependencies(package, set.union(&r))),
),
DerivationTree::External(External::UnusableDependencies(_, r, reason)) => {
Some(DerivationTree::External(External::UnusableDependencies(
package,
set.union(&r),
reason,
)))
}
DerivationTree::External(External::FromDependencyOf(p1, r1, p2, r2)) => {
if p1 == package {
Some(DerivationTree::External(External::FromDependencyOf(
Expand Down Expand Up @@ -169,6 +178,29 @@ impl<P: Package, VS: VersionSet> fmt::Display for External<P, VS> {
)
}
}
Self::UnusableDependencies(package, set, reason) => {
if let Some(reason) = reason {
if set == &VS::full() {
write!(f, "dependencies of {} are unusable: {reason}", package)
} else {
write!(
f,
"dependencies of {} at version {} are unusable: {reason}",
package, set
)
}
} else {
if set == &VS::full() {
write!(f, "dependencies of {} are unusable", package)
} else {
write!(
f,
"dependencies of {} at version {} are unusable",
package, set
)
}
}
}
Self::FromDependencyOf(p, set_p, dep, set_dep) => {
if set_p == &VS::full() && set_dep == &VS::full() {
write!(f, "{} depends on {}", p, dep)
Expand Down

0 comments on commit 073823f

Please sign in to comment.