Skip to content

Commit c8f56b2

Browse files
zaniebkonstin
authored andcommitted
Add an UnusableDependencies incompatibility kind (#4)
1 parent eb256c2 commit c8f56b2

File tree

5 files changed

+62
-3
lines changed

5 files changed

+62
-3
lines changed

examples/unsat_root_message_no_version.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ impl ReportFormatter<Package, Range<SemanticVersion>> for CustomReportFormatter
9999
format!("{package} {package_set} depends on {dependency} {dependency_set}")
100100
}
101101
}
102+
External::UnusableDependencies(package, set, ..) => {
103+
if set == &Range::full() {
104+
format!("dependencies of {package} are unusable")
105+
} else {
106+
format!("dependencies of {package} at version {set} are unusable")
107+
}
108+
}
102109
}
103110
}
104111
}

src/internal/core.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct State<P: Package, VS: VersionSet, Priority: Ord + Clone> {
2525
root_package: P,
2626
root_version: VS::V,
2727

28+
/// The set of incompatibilities for each package.
2829
pub incompatibilities: Map<P, Vec<IncompId<P, VS>>>,
2930

3031
/// Store the ids of incompatibilities that are already contradicted.

src/internal/incompatibility.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ use crate::version_set::VersionSet;
3434
#[derive(Debug, Clone)]
3535
pub struct Incompatibility<P: Package, VS: VersionSet> {
3636
package_terms: SmallMap<P, Term<VS>>,
37+
/// The reason why this version or combination of versions can't be selected.
3738
pub kind: Kind<P, VS>,
3839
}
3940

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

44+
/// The reason why a version or combination of versions can't be selected.
4345
#[derive(Debug, Clone)]
4446
pub enum Kind<P: Package, VS: VersionSet> {
4547
/// Initial incompatibility aiming at picking the root package for the first decision.
@@ -48,6 +50,8 @@ pub enum Kind<P: Package, VS: VersionSet> {
4850
NoVersions(P, VS),
4951
/// Dependencies of the package are unavailable for versions in that range.
5052
UnavailableDependencies(P, VS),
53+
/// Dependencies of the package are unusable for versions in that range.
54+
UnusableDependencies(P, VS, Option<String>),
5155
/// Incompatibility coming from the dependencies of a given package.
5256
FromDependencyOf(P, VS, P, VS),
5357
/// Derived from two causes. Stores cause ids.
@@ -107,6 +111,17 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
107111
}
108112
}
109113

114+
/// Create an incompatibility to remember
115+
/// that a package version is not selectable
116+
/// because its dependencies are not usable.
117+
pub fn unusable_dependencies(package: P, version: VS::V, reason: Option<String>) -> Self {
118+
let set = VS::singleton(version);
119+
Self {
120+
package_terms: SmallMap::One([(package.clone(), Term::Positive(set.clone()))]),
121+
kind: Kind::UnusableDependencies(package, set, reason),
122+
}
123+
}
124+
110125
/// Build an incompatibility from a given dependency.
111126
pub fn from_dependency(package: P, versions: VS, dep: (&P, &VS)) -> Self {
112127
let (p2, set2) = dep;
@@ -123,6 +138,7 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
123138
}
124139
}
125140

141+
/// The two packages causing the incompatibility, if it was derived from dependencies.
126142
pub fn as_dependency(&self) -> Option<(&P, &P)> {
127143
match &self.kind {
128144
Kind::FromDependencyOf(p1, _, p2, _) => Some((p1, p2)),
@@ -255,6 +271,9 @@ impl<P: Package, VS: VersionSet> Incompatibility<P, VS> {
255271
Kind::UnavailableDependencies(package, set) => {
256272
DerivationTree::External(External::UnavailableDependencies(package, set))
257273
}
274+
Kind::UnusableDependencies(package, set, reason) => {
275+
DerivationTree::External(External::UnusableDependencies(package, set, reason))
276+
}
258277
Kind::FromDependencyOf(package, set, dep_package, dep_set) => DerivationTree::External(
259278
External::FromDependencyOf(package, set, dep_package, dep_set),
260279
),

src/report.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ pub enum External<P: Package, VS: VersionSet> {
4949
NoVersions(P, VS),
5050
/// Dependencies of the package are unavailable for versions in that set.
5151
UnavailableDependencies(P, VS),
52+
/// Dependencies of the package are unusable for versions in that set.
53+
UnusableDependencies(P, VS, Option<String>),
5254
/// Incompatibility coming from the dependencies of a given package.
5355
FromDependencyOf(P, VS, P, VS),
5456
}
@@ -124,6 +126,13 @@ impl<P: Package, VS: VersionSet> DerivationTree<P, VS> {
124126
DerivationTree::External(External::UnavailableDependencies(_, r)) => Some(
125127
DerivationTree::External(External::UnavailableDependencies(package, set.union(&r))),
126128
),
129+
DerivationTree::External(External::UnusableDependencies(_, r, reason)) => {
130+
Some(DerivationTree::External(External::UnusableDependencies(
131+
package,
132+
set.union(&r),
133+
reason,
134+
)))
135+
}
127136
DerivationTree::External(External::FromDependencyOf(p1, r1, p2, r2)) => {
128137
if p1 == package {
129138
Some(DerivationTree::External(External::FromDependencyOf(
@@ -169,6 +178,29 @@ impl<P: Package, VS: VersionSet> fmt::Display for External<P, VS> {
169178
)
170179
}
171180
}
181+
Self::UnusableDependencies(package, set, reason) => {
182+
if let Some(reason) = reason {
183+
if set == &VS::full() {
184+
write!(f, "dependencies of {} are unusable: {reason}", package)
185+
} else {
186+
write!(
187+
f,
188+
"dependencies of {} at version {} are unusable: {reason}",
189+
package, set
190+
)
191+
}
192+
} else {
193+
if set == &VS::full() {
194+
write!(f, "dependencies of {} are unusable", package)
195+
} else {
196+
write!(
197+
f,
198+
"dependencies of {} at version {} are unusable",
199+
package, set
200+
)
201+
}
202+
}
203+
}
172204
Self::FromDependencyOf(p, set_p, dep, set_dep) => {
173205
if set_p == &VS::full() && set_dep == &VS::full() {
174206
write!(f, "{} depends on {}", p, dep)

tests/examples.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,12 +231,12 @@ fn confusing_with_lots_of_holes() {
231231
};
232232
assert_eq!(
233233
&DefaultStringReporter::report(&derivation_tree),
234-
r#"Because there is no available version for bar and foo 1 | 2 | 3 | 4 | 5 depends on bar, foo 1 | 2 | 3 | 4 | 5 is forbidden.
235-
And because there is no version of foo in <1 | >1, <2 | >2, <3 | >3, <4 | >4, <5 | >5 and root 1 depends on foo, root 1 is forbidden."#
234+
r#"Because there is no available version for bar and foo ==1, ==2, ==3, ==4, ==5 depends on bar, foo ==1, ==2, ==3, ==4, ==5 is forbidden.
235+
And because there is no version of foo in <1, >1, <2, >2, <3, >3, <4, >4, <5, >5 and root ==1 depends on foo, root ==1 is forbidden."#
236236
);
237237
derivation_tree.collapse_no_versions();
238238
assert_eq!(
239239
&DefaultStringReporter::report(&derivation_tree),
240-
"Because foo depends on bar and root 1 depends on foo, root 1 is forbidden."
240+
"Because foo depends on bar and root ==1 depends on foo, root ==1 is forbidden."
241241
);
242242
}

0 commit comments

Comments
 (0)