diff --git a/Cargo.lock b/Cargo.lock index 69a6bbd6..74037f09 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1761,7 +1761,6 @@ dependencies = [ "ciborium", "criterion", "data-encoding", - "dirs", "elsa", "fs4", "futures", @@ -1769,6 +1768,7 @@ dependencies = [ "http-cache-semantics", "indexmap 2.0.1", "insta", + "itertools 0.11.0", "miette", "mime", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index be70d385..e4cb5847 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,7 @@ rust-version = "1.70" allow-branch = ["main"] consolidate-commits = true tag-prefix = "" + +#[patch.crates-io] +#resolvo = { path="../resolvo" } +#resolvo = { git="https://github.com/mamba-org/resolvo.git", branch="main" } diff --git a/crates/rattler_installs_packages/Cargo.toml b/crates/rattler_installs_packages/Cargo.toml index f2073b6e..8849500d 100644 --- a/crates/rattler_installs_packages/Cargo.toml +++ b/crates/rattler_installs_packages/Cargo.toml @@ -27,6 +27,7 @@ futures = "0.3.28" http = "0.2.9" http-cache-semantics = { version = "1.0.1", default-features = false, features = ["with_serde", "reqwest"] } indexmap = "2.0.1" +itertools = "0.11.0" miette = "5.10.0" mime = "0.3.17" once_cell = "1.18.0" @@ -50,7 +51,6 @@ tracing = { version = "0.1.37", default-features = false, features = ["attribute url = { version = "2.4.1", features = ["serde"] } zip = "0.6.6" resolvo = { version = "0.1.0", optional = true } -dirs = "5.0.1" [dev-dependencies] criterion = "0.5" diff --git a/crates/rattler_installs_packages/src/resolve.rs b/crates/rattler_installs_packages/src/resolve.rs index 9c4feb9b..5f1537a9 100644 --- a/crates/rattler_installs_packages/src/resolve.rs +++ b/crates/rattler_installs_packages/src/resolve.rs @@ -10,6 +10,7 @@ use crate::{ CompareOp, Extra, NormalizedPackageName, PackageDb, PackageName, Requirement, Specifier, Specifiers, UserRequirement, Version, Wheel, }; +use itertools::Itertools; use resolvo::{ Candidates, DefaultSolvableDisplay, Dependencies, DependencyProvider, NameId, Pool, SolvableId, Solver, SolverCache, VersionSet, @@ -140,7 +141,7 @@ impl DependencyProvider for PypiDependencyProvi fn get_candidates(&self, name: NameId) -> Option { let package_name = self.pool.resolve_package_name(name); - tracing::info!("Fetching metadata for {}", package_name); + tracing::info!("collecting {}", package_name); // Get all the metadata for this package let result = task::block_in_place(move || { @@ -159,6 +160,7 @@ impl DependencyProvider for PypiDependencyProvi } }; let mut candidates = Candidates::default(); + let mut no_wheels = Vec::new(); for (version, artifacts) in artifacts.iter() { // Filter only artifacts we can work with let available_artifacts = artifacts @@ -174,7 +176,7 @@ impl DependencyProvider for PypiDependencyProvi // Check if there are wheel artifacts for this version if available_artifacts.is_empty() { // If there are no wheel artifacts, we're just gonna skip it - tracing::warn!("No available wheel artifact {package_name} {version} (skipping)"); + no_wheels.push(version); continue; } @@ -185,7 +187,6 @@ impl DependencyProvider for PypiDependencyProvi .collect::>(); if non_yanked_artifacts.is_empty() { - tracing::info!("{package_name} {version} was yanked (skipping)"); continue; } let solvable_id = self @@ -193,6 +194,16 @@ impl DependencyProvider for PypiDependencyProvi .intern_solvable(name, PypiVersion(version.clone())); candidates.candidates.push(solvable_id); } + + // Print some information about skipped packages + if !no_wheels.is_empty() && package_name.extra().is_none() { + tracing::warn!( + "Not considering {} {} because there are no wheel artifacts available", + package_name, + no_wheels.iter().format(", ") + ); + } + Some(candidates) } @@ -200,6 +211,12 @@ impl DependencyProvider for PypiDependencyProvi let solvable = self.pool.resolve_solvable(solvable); let package_name = self.pool.resolve_package_name(solvable.name_id()); + tracing::info!( + "obtaining dependency information from {}={}", + package_name, + solvable.inner() + ); + // TODO: https://peps.python.org/pep-0508/#environment-markers let env = HashMap::from_iter([ // TODO: We should add some proper values here. @@ -277,6 +294,24 @@ impl DependencyProvider for PypiDependencyProvi .unwrap() }); + // Add constraints that restrict that the extra packages are set to the same version. + if let PypiPackageName::Base(package_name) = package_name { + // Add constraints on the extras of a package + for extra in metadata.extras { + let extra_name_id = self + .pool + .intern_package_name(PypiPackageName::Extra(package_name.clone(), extra)); + let specifiers = Specifiers(vec![Specifier { + op: CompareOp::Equal, + value: solvable.inner().0.to_string(), + }]); + let version_set_id = self + .pool + .intern_version_set(extra_name_id, specifiers.into()); + dependencies.constrains.push(version_set_id); + } + } + for requirement in metadata.requires_dist { // Evaluate environment markers if let Some(env_marker) = &requirement.env_marker_expr {