471a1d657d
## Summary This PR enables the proof-of-concept resolver to backtrack by way of using the `pubgrub-rs` crate. Rather than using PubGrub as a _framework_ (implementing the `DependencyProvider` trait, letting PubGrub call us), I've instead copied over PubGrub's primary solver hook (which is only ~100 lines or so) and modified it for our purposes (e.g., made it async). There's a lot to improve here, but it's a start that will let us understand PubGrub's appropriateness for this problem space. A few observations: - In simple cases, the resolver is slower than our current (naive) resolver. I think it's just that the pipelining isn't as efficient as in the naive case, where we can just stream package and version fetches concurrently without any bottlenecks. - A lot of the code here relates to bridging PubGrub with our own abstractions -- so we need a `PubGrubPackage`, a `PubGrubVersion`, etc.
48 lines
1.7 KiB
Rust
48 lines
1.7 KiB
Rust
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
use pubgrub::error::PubGrubError;
|
|
use pubgrub::range::Range;
|
|
use pubgrub::report::{DefaultStringReporter, Reporter};
|
|
use pubgrub::solver::{resolve, OfflineDependencyProvider};
|
|
use pubgrub::version::SemanticVersion;
|
|
|
|
// https://github.com/dart-lang/pub/blob/master/doc/solver.md#linear-error-reporting
|
|
fn main() {
|
|
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
|
|
#[rustfmt::skip]
|
|
// root 1.0.0 depends on foo ^1.0.0 and baz ^1.0.0
|
|
dependency_provider.add_dependencies(
|
|
"root", (1, 0, 0),
|
|
vec![
|
|
("foo", Range::between((1, 0, 0), (2, 0, 0))),
|
|
("baz", Range::between((1, 0, 0), (2, 0, 0))),
|
|
],
|
|
);
|
|
#[rustfmt::skip]
|
|
// foo 1.0.0 depends on bar ^2.0.0
|
|
dependency_provider.add_dependencies(
|
|
"foo", (1, 0, 0),
|
|
vec![("bar", Range::between((2, 0, 0), (3, 0, 0)))],
|
|
);
|
|
#[rustfmt::skip]
|
|
// bar 2.0.0 depends on baz ^3.0.0
|
|
dependency_provider.add_dependencies(
|
|
"bar", (2, 0, 0),
|
|
vec![("baz", Range::between((3, 0, 0), (4, 0, 0)))],
|
|
);
|
|
// baz 1.0.0 and 3.0.0 have no dependencies
|
|
dependency_provider.add_dependencies("baz", (1, 0, 0), vec![]);
|
|
dependency_provider.add_dependencies("baz", (3, 0, 0), vec![]);
|
|
|
|
// Run the algorithm.
|
|
match resolve(&dependency_provider, "root", (1, 0, 0)) {
|
|
Ok(sol) => println!("{:?}", sol),
|
|
Err(PubGrubError::NoSolution(mut derivation_tree)) => {
|
|
derivation_tree.collapse_no_versions();
|
|
eprintln!("{}", DefaultStringReporter::report(&derivation_tree));
|
|
std::process::exit(1);
|
|
}
|
|
Err(err) => panic!("{:?}", err),
|
|
};
|
|
}
|