Skip to content

Experimental new Interval API with continuous space for versions #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
run: cargo build --verbose

- name: Run tests
run: cargo test --features=serde --verbose
run: cargo test --verbose

clippy:
name: No warnings from Clippy
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ include = ["Cargo.toml", "LICENSE", "README.md", "src/**", "tests/**", "examples
thiserror = "1.0"
rustc-hash = "1.1.0"
serde = { version = "1.0", features = ["derive"], optional = true }
log = { version = "0.4.14", default-features = false } # for debug logs in tests

[dev-dependencies]
proptest = "0.10.1"
ron = "0.6"
varisat = "0.2.2"
criterion = "0.3"
env_logger = "0.9.0"

[[bench]]
name = "large_case"
Expand Down
7 changes: 4 additions & 3 deletions examples/branching_error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// https://github.com/dart-lang/pub/blob/master/doc/solver.md#branching-error-reporting
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider =
OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
#[rustfmt::skip]
// root 1.0.0 depends on foo ^1.0.0
dependency_provider.add_dependencies(
Expand Down
28 changes: 18 additions & 10 deletions examples/caching_dependency_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@ use std::cell::RefCell;
use std::error::Error;

use pubgrub::package::Package;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::solver::{resolve, Dependencies, DependencyProvider, OfflineDependencyProvider};
use pubgrub::version::{NumberVersion, Version};
use pubgrub::version_trait::{Interval, NumberInterval, NumberVersion, Version};

// An example implementing caching dependency provider that will
// store queried dependencies in memory and check them before querying more from remote.
struct CachingDependencyProvider<P: Package, V: Version, DP: DependencyProvider<P, V>> {
struct CachingDependencyProvider<
P: Package,
I: Interval<V>,
V: Version,
DP: DependencyProvider<P, I, V>,
> {
remote_dependencies: DP,
cached_dependencies: RefCell<OfflineDependencyProvider<P, V>>,
cached_dependencies: RefCell<OfflineDependencyProvider<P, I, V>>,
}

impl<P: Package, V: Version, DP: DependencyProvider<P, V>> CachingDependencyProvider<P, V, DP> {
impl<P: Package, I: Interval<V>, V: Version, DP: DependencyProvider<P, I, V>>
CachingDependencyProvider<P, I, V, DP>
{
pub fn new(remote_dependencies_provider: DP) -> Self {
CachingDependencyProvider {
remote_dependencies: remote_dependencies_provider,
Expand All @@ -24,10 +31,10 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> CachingDependencyProv
}
}

impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P, V>
for CachingDependencyProvider<P, V, DP>
impl<P: Package, I: Interval<V>, V: Version, DP: DependencyProvider<P, I, V>>
DependencyProvider<P, I, V> for CachingDependencyProvider<P, I, V, DP>
{
fn choose_package_version<T: std::borrow::Borrow<P>, U: std::borrow::Borrow<Range<V>>>(
fn choose_package_version<T: std::borrow::Borrow<P>, U: std::borrow::Borrow<Range<I, V>>>(
&self,
packages: impl Iterator<Item = (T, U)>,
) -> Result<(T, Option<V>), Box<dyn Error>> {
Expand All @@ -39,7 +46,7 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P,
&self,
package: &P,
version: &V,
) -> Result<Dependencies<P, V>, Box<dyn Error>> {
) -> Result<Dependencies<P, I, V>, Box<dyn Error>> {
let mut cache = self.cached_dependencies.borrow_mut();
match cache.get_dependencies(package, version) {
Ok(Dependencies::Unknown) => {
Expand All @@ -65,7 +72,8 @@ impl<P: Package, V: Version, DP: DependencyProvider<P, V>> DependencyProvider<P,

fn main() {
// Simulating remote provider locally.
let mut remote_dependencies_provider = OfflineDependencyProvider::<&str, NumberVersion>::new();
let mut remote_dependencies_provider =
OfflineDependencyProvider::<&str, NumberInterval, NumberVersion>::new();

// Add dependencies as needed. Here only root package is added.
remote_dependencies_provider.add_dependencies("root", 1, Vec::new());
Expand Down
12 changes: 6 additions & 6 deletions examples/doc_interface.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::NumberVersion;
use pubgrub::version_trait::{NumberInterval, NumberVersion};

// `root` depends on `menu` and `icons`
// `menu` depends on `dropdown`
// `dropdown` depends on `icons`
// `icons` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, NumberVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, NumberInterval, NumberVersion>::new();
dependency_provider.add_dependencies(
"root", 1, vec![("menu", Range::any()), ("icons", Range::any())],
"root", 1, vec![("menu", Range::full()), ("icons", Range::full())],
);
dependency_provider.add_dependencies("menu", 1, vec![("dropdown", Range::any())]);
dependency_provider.add_dependencies("dropdown", 1, vec![("icons", Range::any())]);
dependency_provider.add_dependencies("menu", 1, vec![("dropdown", Range::full())]);
dependency_provider.add_dependencies("dropdown", 1, vec![("icons", Range::full())]);
dependency_provider.add_dependencies("icons", 1, vec![]);

// Run the algorithm.
Expand Down
22 changes: 11 additions & 11 deletions examples/doc_interface_error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// `root` depends on `menu`, `icons 1.0.0` and `intl 5.0.0`
// `menu 1.0.0` depends on `dropdown < 2.0.0`
Expand All @@ -15,12 +15,12 @@ use pubgrub::version::SemanticVersion;
// `intl` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), vec![
("menu", Range::any()),
("icons", Range::exact((1, 0, 0))),
("intl", Range::exact((5, 0, 0))),
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
("intl", Range::singleton((5, 0, 0))),
]);

// Dependencies of the menu lib.
Expand All @@ -45,19 +45,19 @@ fn main() {

// Dependencies of the dropdown lib.
dependency_provider.add_dependencies("dropdown", (1, 8, 0), vec![
("intl", Range::exact((3, 0, 0))),
("intl", Range::singleton((3, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 0, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 1, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 2, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 3, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);

// Icons have no dependencies.
Expand Down
18 changes: 9 additions & 9 deletions examples/doc_interface_semantic.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, SemanticVersion};

// `root` depends on `menu` and `icons 1.0.0`
// `menu 1.0.0` depends on `dropdown < 2.0.0`
Expand All @@ -14,11 +14,11 @@ use pubgrub::version::SemanticVersion;
// `icons` has no dependency
#[rustfmt::skip]
fn main() {
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticVersion>::new();
let mut dependency_provider = OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
// Direct dependencies: menu and icons.
dependency_provider.add_dependencies("root", (1, 0, 0), vec![
("menu", Range::any()),
("icons", Range::exact((1, 0, 0))),
("menu", Range::full()),
("icons", Range::singleton((1, 0, 0))),
]);

// Dependencies of the menu lib.
Expand All @@ -44,16 +44,16 @@ fn main() {
// Dependencies of the dropdown lib.
dependency_provider.add_dependencies("dropdown", (1, 8, 0), vec![]);
dependency_provider.add_dependencies("dropdown", (2, 0, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 1, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 2, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);
dependency_provider.add_dependencies("dropdown", (2, 3, 0), vec![
("icons", Range::exact((2, 0, 0))),
("icons", Range::singleton((2, 0, 0))),
]);

// Icons has no dependency.
Expand Down
7 changes: 4 additions & 3 deletions examples/linear_error_reporting.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// SPDX-License-Identifier: MPL-2.0

use pubgrub::error::PubGrubError;
use pubgrub::range::Range;
use pubgrub::range_trait::Range;
use pubgrub::report::{DefaultStringReporter, Reporter};
use pubgrub::solver::{resolve, OfflineDependencyProvider};
use pubgrub::version::SemanticVersion;
use pubgrub::version_trait::{SemanticInterval, 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();
let mut dependency_provider =
OfflineDependencyProvider::<&str, SemanticInterval, SemanticVersion>::new();
#[rustfmt::skip]
// root 1.0.0 depends on foo ^1.0.0 and baz ^1.0.0
dependency_provider.add_dependencies(
Expand Down
7 changes: 4 additions & 3 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ use thiserror::Error;

use crate::package::Package;
use crate::report::DerivationTree;
use crate::version::Version;
use crate::version_trait::{Interval, Version};
use std::fmt::Debug;

/// Errors that may occur while solving dependencies.
#[derive(Error, Debug)]
pub enum PubGrubError<P: Package, V: Version> {
pub enum PubGrubError<P: Package, I: Interval<V> + Debug, V: Version> {
/// There is no solution for this set of dependencies.
#[error("No solution")]
NoSolution(DerivationTree<P, V>),
NoSolution(DerivationTree<P, I, V>),

/// Error arising when the implementer of
/// [DependencyProvider](crate::solver::DependencyProvider)
Expand Down
Loading