Skip to content

Commit

Permalink
PubGrub resolver initial impl, blocking, no-graph
Browse files Browse the repository at this point in the history
commit-id:d55b5ecb
  • Loading branch information
maciektr committed Jul 17, 2024
1 parent 5e3f300 commit 3c2d40c
Show file tree
Hide file tree
Showing 10 changed files with 463 additions and 39 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,20 @@ ntest = "0.9"
num-bigint = { version = "0.4", features = ["rand"] }
num-traits = "0.2"
once_cell = "1"
once_map = "0.4"
pathdiff = { version = "0.2", features = ["camino"] }
petgraph = "0.6"
predicates = "3"
proc-macro2 = "1"
pubgrub = { git = "https://github.com/pubgrub-rs/pubgrub.git", branch = "dev" }
quote = "1"
ra_ap_toolchain = "0.0.218"
rayon = "1.10"
redb = "2.1.1"
reqwest = { version = "0.11", features = ["gzip", "brotli", "deflate", "json", "stream"], default-features = false }
salsa = "0.16.1"
semver = { version = "1", features = ["serde"] }
semver-pubgrub = { git = "https://github.com/pubgrub-rs/semver-pubgrub.git" }
serde = { version = "1", features = ["serde_derive"] }
serde-untagged = "0.1"
serde-value = "0.7"
Expand Down
4 changes: 3 additions & 1 deletion scarb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ directories.workspace = true
dunce.workspace = true
fs4.workspace = true
futures.workspace = true
gix.workspace = true
gix-path.workspace = true
gix.workspace = true
glob.workspace = true
ignore.workspace = true
include_dir.workspace = true
Expand All @@ -55,13 +55,15 @@ libloading.workspace = true
once_cell.workspace = true
pathdiff.workspace = true
petgraph.workspace = true
pubgrub.workspace = true
ra_ap_toolchain.workspace = true
redb.workspace = true
reqwest.workspace = true
scarb-build-metadata = { path = "../utils/scarb-build-metadata" }
scarb-metadata = { path = "../scarb-metadata", default-features = false, features = ["builder"] }
scarb-stable-hash = { path = "../utils/scarb-stable-hash" }
scarb-ui = { path = "../utils/scarb-ui" }
semver-pubgrub.workspace = true
semver.workspace = true
serde-untagged.workspace = true
serde-value.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion scarb/src/core/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub(crate) mod mock {
let summary = Summary::builder()
.package_id(package_id)
.dependencies(dependencies)
.no_core(package_id.is_core())
.no_core(package_id.name == PackageName::CORE)
.build();

let manifest = Box::new(
Expand Down
8 changes: 7 additions & 1 deletion scarb/src/ops/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,13 @@ pub fn resolve_workspace_with_opts(
read_lockfile(ws)?
};

let resolve = resolver::resolve(&members_summaries, &patched, lockfile).await?;
let resolve = resolver::resolve(
&members_summaries,
&patched,
lockfile,
ws.config().tokio_handle(),
)
.await?;

write_lockfile(Lockfile::from_resolve(&resolve), ws)?;

Expand Down
63 changes: 63 additions & 0 deletions scarb/src/resolver/algorithm/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
use crate::core::lockfile::Lockfile;
use crate::core::registry::Registry;
use crate::core::{PackageId, PackageName, Resolve, Summary};
use crate::resolver::algorithm::provider::{PubGrubDependencyProvider, PubGrubPackage};
use crate::resolver::algorithm::solution::build_resolve;
use anyhow::bail;
use indoc::indoc;
use pubgrub::type_aliases::SelectedDependencies;
use std::collections::{HashMap, HashSet};
use tokio::runtime::Handle;
use tokio::task::block_in_place;

mod provider;
mod solution;

#[allow(clippy::dbg_macro)]
#[allow(dead_code)]
pub async fn resolve<'c>(
summaries: &[Summary],
registry: &dyn Registry,
_lockfile: Lockfile,
handle: &'c Handle,
) -> anyhow::Result<Resolve> {
let main_package_ids: HashSet<PackageId> =
HashSet::from_iter(summaries.iter().map(|sum| sum.package_id));
block_in_place(|| {
let summary = summaries.iter().next().unwrap();
let package: PubGrubPackage = summary.into();
let version = summary.package_id.version.clone();
let provider = PubGrubDependencyProvider::new(registry, handle, main_package_ids.clone());

let solution = pubgrub::solver::resolve(&provider, package, version)
.map_err(|err| anyhow::format_err!("failed to resolve: {:?}", err))?;

dbg!(&solution);

validate_solution(&solution)?;
build_resolve(&provider, solution)
})
}

fn validate_solution(
solution: &SelectedDependencies<PubGrubDependencyProvider<'_, '_>>,
) -> anyhow::Result<()> {
// Same package, different sources.
let mut seen: HashMap<PackageName, PubGrubPackage> = Default::default();
for pkg in solution.keys() {
if let Some(existing) = seen.get(&pkg.name) {
bail!(
indoc! {"
found dependencies on the same package `{}` coming from incompatible \
sources:
source 1: {}
source 2: {}
"},
pkg.name,
existing.source_id,
pkg.source_id
);
}
seen.insert(pkg.name.clone(), pkg.clone());
}
Ok(())
}
Loading

0 comments on commit 3c2d40c

Please sign in to comment.