mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-01 20:31:12 +00:00
uv-resolver: use named fields for some PubGrubPackage variants
I'm planning to add another field here (markers), which puts a lot of stress on the positional approach. So let's just switch over to named fields.
This commit is contained in:
parent
44fe0f6749
commit
eac8221718
8 changed files with 216 additions and 141 deletions
|
|
@ -127,7 +127,7 @@ fn collapse_extra_proxies(
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
DerivationTree::External(External::FromDependencyOf(
|
DerivationTree::External(External::FromDependencyOf(
|
||||||
PubGrubPackage::Extra(..),
|
PubGrubPackage::Extra { .. },
|
||||||
..,
|
..,
|
||||||
)),
|
)),
|
||||||
ref mut cause,
|
ref mut cause,
|
||||||
|
|
@ -138,7 +138,7 @@ fn collapse_extra_proxies(
|
||||||
(
|
(
|
||||||
ref mut cause,
|
ref mut cause,
|
||||||
DerivationTree::External(External::FromDependencyOf(
|
DerivationTree::External(External::FromDependencyOf(
|
||||||
PubGrubPackage::Extra(..),
|
PubGrubPackage::Extra { .. },
|
||||||
..,
|
..,
|
||||||
)),
|
)),
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -255,8 +255,8 @@ impl NoSolutionError {
|
||||||
BTreeSet::from([python_requirement.target().deref().clone()]),
|
BTreeSet::from([python_requirement.target().deref().clone()]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PubGrubPackage::Extra(_, _, _) => {}
|
PubGrubPackage::Extra { .. } => {}
|
||||||
PubGrubPackage::Package(name, _, _) => {
|
PubGrubPackage::Package { name, .. } => {
|
||||||
// Avoid including available versions for packages that exist in the derivation
|
// Avoid including available versions for packages that exist in the derivation
|
||||||
// tree, but were never visited during resolution. We _may_ have metadata for
|
// tree, but were never visited during resolution. We _may_ have metadata for
|
||||||
// these packages, but it's non-deterministic, and omitting them ensures that
|
// these packages, but it's non-deterministic, and omitting them ensures that
|
||||||
|
|
@ -304,7 +304,7 @@ impl NoSolutionError {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut new = FxHashMap::default();
|
let mut new = FxHashMap::default();
|
||||||
for package in self.derivation_tree.packages() {
|
for package in self.derivation_tree.packages() {
|
||||||
if let PubGrubPackage::Package(name, _, _) = package {
|
if let PubGrubPackage::Package { name, .. } = package {
|
||||||
if let Some(reason) = unavailable_packages.get(name) {
|
if let Some(reason) = unavailable_packages.get(name) {
|
||||||
new.insert(name.clone(), reason.clone());
|
new.insert(name.clone(), reason.clone());
|
||||||
}
|
}
|
||||||
|
|
@ -322,7 +322,7 @@ impl NoSolutionError {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut new = FxHashMap::default();
|
let mut new = FxHashMap::default();
|
||||||
for package in self.derivation_tree.packages() {
|
for package in self.derivation_tree.packages() {
|
||||||
if let PubGrubPackage::Package(name, _, _) = package {
|
if let PubGrubPackage::Package { name, .. } = package {
|
||||||
if let Some(versions) = incomplete_packages.get(name) {
|
if let Some(versions) = incomplete_packages.get(name) {
|
||||||
for entry in versions.iter() {
|
for entry in versions.iter() {
|
||||||
let (version, reason) = entry.pair();
|
let (version, reason) = entry.pair();
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ fn add_requirements(
|
||||||
let PubGrubRequirement { package, version } = result?;
|
let PubGrubRequirement { package, version } = result?;
|
||||||
|
|
||||||
match &package {
|
match &package {
|
||||||
PubGrubPackage::Package(name, ..) => {
|
PubGrubPackage::Package { name, .. } => {
|
||||||
// Detect self-dependencies.
|
// Detect self-dependencies.
|
||||||
if source_name.is_some_and(|source_name| source_name == name) {
|
if source_name.is_some_and(|source_name| source_name == name) {
|
||||||
warn!("{name} has a dependency on itself");
|
warn!("{name} has a dependency on itself");
|
||||||
|
|
@ -112,7 +112,7 @@ fn add_requirements(
|
||||||
|
|
||||||
dependencies.push((package.clone(), version.clone()));
|
dependencies.push((package.clone(), version.clone()));
|
||||||
}
|
}
|
||||||
PubGrubPackage::Extra(name, extra, ..) => {
|
PubGrubPackage::Extra { name, extra, .. } => {
|
||||||
// Recursively add the dependencies of the current package (e.g., `black` depending on
|
// Recursively add the dependencies of the current package (e.g., `black` depending on
|
||||||
// `black[colorama]`).
|
// `black[colorama]`).
|
||||||
if source_name.is_some_and(|source_name| source_name == name) {
|
if source_name.is_some_and(|source_name| source_name == name) {
|
||||||
|
|
@ -158,7 +158,7 @@ fn add_requirements(
|
||||||
PubGrubRequirement::from_constraint(constraint, urls, locals)?;
|
PubGrubRequirement::from_constraint(constraint, urls, locals)?;
|
||||||
|
|
||||||
// Ignore self-dependencies.
|
// Ignore self-dependencies.
|
||||||
if let PubGrubPackage::Package(name, ..) = &package {
|
if let PubGrubPackage::Package { name, .. } = &package {
|
||||||
// Detect self-dependencies.
|
// Detect self-dependencies.
|
||||||
if source_name.is_some_and(|source_name| source_name == name) {
|
if source_name.is_some_and(|source_name| source_name == name) {
|
||||||
warn!("{name} has a dependency on itself");
|
warn!("{name} has a dependency on itself");
|
||||||
|
|
@ -244,11 +244,11 @@ impl PubGrubRequirement {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
package: PubGrubPackage::Package(
|
package: PubGrubPackage::Package {
|
||||||
requirement.name.clone(),
|
name: requirement.name.clone(),
|
||||||
extra,
|
extra,
|
||||||
Some(expected.clone()),
|
url: Some(expected.clone()),
|
||||||
),
|
},
|
||||||
version: Range::full(),
|
version: Range::full(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -269,11 +269,11 @@ impl PubGrubRequirement {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
package: PubGrubPackage::Package(
|
package: PubGrubPackage::Package {
|
||||||
requirement.name.clone(),
|
name: requirement.name.clone(),
|
||||||
extra,
|
extra,
|
||||||
Some(expected.clone()),
|
url: Some(expected.clone()),
|
||||||
),
|
},
|
||||||
version: Range::full(),
|
version: Range::full(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -294,11 +294,11 @@ impl PubGrubRequirement {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
package: PubGrubPackage::Package(
|
package: PubGrubPackage::Package {
|
||||||
requirement.name.clone(),
|
name: requirement.name.clone(),
|
||||||
extra,
|
extra,
|
||||||
Some(expected.clone()),
|
url: Some(expected.clone()),
|
||||||
),
|
},
|
||||||
version: Range::full(),
|
version: Range::full(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ pub enum PubGrubPackage {
|
||||||
/// A Python version.
|
/// A Python version.
|
||||||
Python(PubGrubPython),
|
Python(PubGrubPython),
|
||||||
/// A Python package.
|
/// A Python package.
|
||||||
Package(
|
Package {
|
||||||
PackageName,
|
name: PackageName,
|
||||||
Option<ExtraName>,
|
extra: Option<ExtraName>,
|
||||||
/// The URL of the package, if it was specified in the requirement.
|
/// The URL of the package, if it was specified in the requirement.
|
||||||
///
|
///
|
||||||
/// There are a few challenges that come with URL-based packages, and how they map to
|
/// There are a few challenges that come with URL-based packages, and how they map to
|
||||||
|
|
@ -59,8 +59,8 @@ pub enum PubGrubPackage {
|
||||||
/// we're going to have a dependency that's provided as a URL, we _need_ to visit the URL
|
/// we're going to have a dependency that's provided as a URL, we _need_ to visit the URL
|
||||||
/// version before the registry version. So we could just error if we visit a URL variant
|
/// version before the registry version. So we could just error if we visit a URL variant
|
||||||
/// _after_ a registry variant.
|
/// _after_ a registry variant.
|
||||||
Option<VerbatimParsedUrl>,
|
url: Option<VerbatimParsedUrl>,
|
||||||
),
|
},
|
||||||
/// A proxy package to represent a dependency with an extra (e.g., `black[colorama]`).
|
/// A proxy package to represent a dependency with an extra (e.g., `black[colorama]`).
|
||||||
///
|
///
|
||||||
/// For a given package `black`, and an extra `colorama`, we create a virtual package
|
/// For a given package `black`, and an extra `colorama`, we create a virtual package
|
||||||
|
|
@ -74,7 +74,11 @@ pub enum PubGrubPackage {
|
||||||
/// the exact same version of the base variant. Without the proxy package, then when provided
|
/// the exact same version of the base variant. Without the proxy package, then when provided
|
||||||
/// requirements like `black==23.0.1` and `black[colorama]`, PubGrub may attempt to retrieve
|
/// requirements like `black==23.0.1` and `black[colorama]`, PubGrub may attempt to retrieve
|
||||||
/// metadata for `black[colorama]` versions other than `23.0.1`.
|
/// metadata for `black[colorama]` versions other than `23.0.1`.
|
||||||
Extra(PackageName, ExtraName, Option<VerbatimParsedUrl>),
|
Extra {
|
||||||
|
name: PackageName,
|
||||||
|
extra: ExtraName,
|
||||||
|
url: Option<VerbatimParsedUrl>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PubGrubPackage {
|
impl PubGrubPackage {
|
||||||
|
|
@ -82,9 +86,9 @@ impl PubGrubPackage {
|
||||||
pub(crate) fn from_package(name: PackageName, extra: Option<ExtraName>, urls: &Urls) -> Self {
|
pub(crate) fn from_package(name: PackageName, extra: Option<ExtraName>, urls: &Urls) -> Self {
|
||||||
let url = urls.get(&name).cloned();
|
let url = urls.get(&name).cloned();
|
||||||
if let Some(extra) = extra {
|
if let Some(extra) = extra {
|
||||||
Self::Extra(name, extra, url)
|
Self::Extra { name, extra, url }
|
||||||
} else {
|
} else {
|
||||||
Self::Package(name, extra, url)
|
Self::Package { name, extra, url }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -108,11 +112,17 @@ impl std::fmt::Display for PubGrubPackage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::Python(_) => write!(f, "Python"),
|
Self::Python(_) => write!(f, "Python"),
|
||||||
Self::Package(name, None, ..) => write!(f, "{name}"),
|
Self::Package {
|
||||||
Self::Package(name, Some(extra), ..) => {
|
name, extra: None, ..
|
||||||
|
} => write!(f, "{name}"),
|
||||||
|
Self::Package {
|
||||||
|
name,
|
||||||
|
extra: Some(extra),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
write!(f, "{name}[{extra}]")
|
write!(f, "{name}[{extra}]")
|
||||||
}
|
}
|
||||||
Self::Extra(name, extra, ..) => write!(f, "{name}[{extra}]"),
|
Self::Extra { name, extra, .. } => write!(f, "{name}[{extra}]"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,12 @@ impl PubGrubPriorities {
|
||||||
PubGrubPackage::Root(_) => {}
|
PubGrubPackage::Root(_) => {}
|
||||||
PubGrubPackage::Python(_) => {}
|
PubGrubPackage::Python(_) => {}
|
||||||
|
|
||||||
PubGrubPackage::Extra(name, _, None) | PubGrubPackage::Package(name, _, None) => {
|
PubGrubPackage::Extra {
|
||||||
|
name, url: None, ..
|
||||||
|
}
|
||||||
|
| PubGrubPackage::Package {
|
||||||
|
name, url: None, ..
|
||||||
|
} => {
|
||||||
match self.0.entry(name.clone()) {
|
match self.0.entry(name.clone()) {
|
||||||
std::collections::hash_map::Entry::Occupied(mut entry) => {
|
std::collections::hash_map::Entry::Occupied(mut entry) => {
|
||||||
// Preserve the original index.
|
// Preserve the original index.
|
||||||
|
|
@ -61,7 +66,12 @@ impl PubGrubPriorities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PubGrubPackage::Extra(name, _, Some(_)) | PubGrubPackage::Package(name, _, Some(_)) => {
|
PubGrubPackage::Extra {
|
||||||
|
name, url: Some(_), ..
|
||||||
|
}
|
||||||
|
| PubGrubPackage::Package {
|
||||||
|
name, url: Some(_), ..
|
||||||
|
} => {
|
||||||
match self.0.entry(name.clone()) {
|
match self.0.entry(name.clone()) {
|
||||||
std::collections::hash_map::Entry::Occupied(mut entry) => {
|
std::collections::hash_map::Entry::Occupied(mut entry) => {
|
||||||
// Preserve the original index.
|
// Preserve the original index.
|
||||||
|
|
@ -94,8 +104,8 @@ impl PubGrubPriorities {
|
||||||
match package {
|
match package {
|
||||||
PubGrubPackage::Root(_) => Some(PubGrubPriority::Root),
|
PubGrubPackage::Root(_) => Some(PubGrubPriority::Root),
|
||||||
PubGrubPackage::Python(_) => Some(PubGrubPriority::Root),
|
PubGrubPackage::Python(_) => Some(PubGrubPriority::Root),
|
||||||
PubGrubPackage::Extra(name, _, _) => self.0.get(name).copied(),
|
PubGrubPackage::Extra { name, .. } => self.0.get(name).copied(),
|
||||||
PubGrubPackage::Package(name, _, _) => self.0.get(name).copied(),
|
PubGrubPackage::Package { name, .. } => self.0.get(name).copied(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,14 +155,14 @@ impl ReportFormatter<PubGrubPackage, Range<Version>, UnavailableReason>
|
||||||
let terms_vec: Vec<_> = terms.iter().collect();
|
let terms_vec: Vec<_> = terms.iter().collect();
|
||||||
match terms_vec.as_slice() {
|
match terms_vec.as_slice() {
|
||||||
[] | [(PubGrubPackage::Root(_), _)] => "the requirements are unsatisfiable".into(),
|
[] | [(PubGrubPackage::Root(_), _)] => "the requirements are unsatisfiable".into(),
|
||||||
[(package @ PubGrubPackage::Package(..), Term::Positive(range))] => {
|
[(package @ PubGrubPackage::Package { .. }, Term::Positive(range))] => {
|
||||||
let range = self.simplify_set(range, package);
|
let range = self.simplify_set(range, package);
|
||||||
format!(
|
format!(
|
||||||
"{} cannot be used",
|
"{} cannot be used",
|
||||||
PackageRange::compatibility(package, &range)
|
PackageRange::compatibility(package, &range)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
[(package @ PubGrubPackage::Package(..), Term::Negative(range))] => {
|
[(package @ PubGrubPackage::Package { .. }, Term::Negative(range))] => {
|
||||||
let range = self.simplify_set(range, package);
|
let range = self.simplify_set(range, package);
|
||||||
format!(
|
format!(
|
||||||
"{} must be used",
|
"{} must be used",
|
||||||
|
|
@ -399,10 +399,10 @@ impl PubGrubReportFormatter<'_> {
|
||||||
) -> IndexSet<PubGrubHint> {
|
) -> IndexSet<PubGrubHint> {
|
||||||
/// Returns `true` if pre-releases were allowed for a package.
|
/// Returns `true` if pre-releases were allowed for a package.
|
||||||
fn allowed_prerelease(package: &PubGrubPackage, selector: &CandidateSelector) -> bool {
|
fn allowed_prerelease(package: &PubGrubPackage, selector: &CandidateSelector) -> bool {
|
||||||
let PubGrubPackage::Package(package, ..) = package else {
|
let PubGrubPackage::Package { name, .. } = package else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
selector.prerelease_strategy().allows(package)
|
selector.prerelease_strategy().allows(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut hints = IndexSet::default();
|
let mut hints = IndexSet::default();
|
||||||
|
|
@ -457,7 +457,7 @@ impl PubGrubReportFormatter<'_> {
|
||||||
let no_find_links =
|
let no_find_links =
|
||||||
index_locations.flat_index().peekable().peek().is_none();
|
index_locations.flat_index().peekable().peek().is_none();
|
||||||
|
|
||||||
if let PubGrubPackage::Package(name, ..) = package {
|
if let PubGrubPackage::Package { name, .. } = package {
|
||||||
// Add hints due to the package being entirely unavailable.
|
// Add hints due to the package being entirely unavailable.
|
||||||
match unavailable_packages.get(name) {
|
match unavailable_packages.get(name) {
|
||||||
Some(UnavailablePackage::NoIndex) => {
|
Some(UnavailablePackage::NoIndex) => {
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,12 @@ impl ResolutionGraph {
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
for (package, version) in selection {
|
for (package, version) in selection {
|
||||||
match package {
|
match package {
|
||||||
PubGrubPackage::Package(package_name, Some(extra), None) => {
|
PubGrubPackage::Package {
|
||||||
let dist = PubGrubDistribution::from_registry(package_name, version);
|
name,
|
||||||
|
extra: Some(extra),
|
||||||
|
url: None,
|
||||||
|
} => {
|
||||||
|
let dist = PubGrubDistribution::from_registry(name, version);
|
||||||
|
|
||||||
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
|
|
@ -75,15 +79,13 @@ impl ResolutionGraph {
|
||||||
|
|
||||||
if archive.metadata.provides_extras.contains(extra) {
|
if archive.metadata.provides_extras.contains(extra) {
|
||||||
extras
|
extras
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_insert_with(Vec::new)
|
.or_insert_with(Vec::new)
|
||||||
.push(extra.clone());
|
.push(extra.clone());
|
||||||
} else {
|
} else {
|
||||||
let dist = pins
|
let dist = pins
|
||||||
.get(package_name, version)
|
.get(name, version)
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| panic!("Every package should be pinned: {name:?}"))
|
||||||
panic!("Every package should be pinned: {package_name:?}")
|
|
||||||
})
|
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
diagnostics.push(Diagnostic::MissingExtra {
|
diagnostics.push(Diagnostic::MissingExtra {
|
||||||
|
|
@ -92,16 +94,19 @@ impl ResolutionGraph {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PubGrubPackage::Package(package_name, Some(extra), Some(url)) => {
|
PubGrubPackage::Package {
|
||||||
if let Some(editable) = editables.get(package_name) {
|
name,
|
||||||
|
extra: Some(extra),
|
||||||
|
url: Some(url),
|
||||||
|
} => {
|
||||||
|
if let Some(editable) = editables.get(name) {
|
||||||
if editable.metadata.provides_extras.contains(extra) {
|
if editable.metadata.provides_extras.contains(extra) {
|
||||||
extras
|
extras
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_insert_with(Vec::new)
|
.or_insert_with(Vec::new)
|
||||||
.push(extra.clone());
|
.push(extra.clone());
|
||||||
} else {
|
} else {
|
||||||
let dist =
|
let dist = Dist::from_editable(name.clone(), editable.built.clone())?;
|
||||||
Dist::from_editable(package_name.clone(), editable.built.clone())?;
|
|
||||||
|
|
||||||
diagnostics.push(Diagnostic::MissingExtra {
|
diagnostics.push(Diagnostic::MissingExtra {
|
||||||
dist: dist.into(),
|
dist: dist.into(),
|
||||||
|
|
@ -109,7 +114,7 @@ impl ResolutionGraph {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let dist = PubGrubDistribution::from_url(package_name, url);
|
let dist = PubGrubDistribution::from_url(name, url);
|
||||||
|
|
||||||
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
|
|
@ -127,12 +132,11 @@ impl ResolutionGraph {
|
||||||
|
|
||||||
if archive.metadata.provides_extras.contains(extra) {
|
if archive.metadata.provides_extras.contains(extra) {
|
||||||
extras
|
extras
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_insert_with(Vec::new)
|
.or_insert_with(Vec::new)
|
||||||
.push(extra.clone());
|
.push(extra.clone());
|
||||||
} else {
|
} else {
|
||||||
let dist =
|
let dist = Dist::from_url(name.clone(), url_to_precise(url.clone()))?;
|
||||||
Dist::from_url(package_name.clone(), url_to_precise(url.clone()))?;
|
|
||||||
|
|
||||||
diagnostics.push(Diagnostic::MissingExtra {
|
diagnostics.push(Diagnostic::MissingExtra {
|
||||||
dist: dist.into(),
|
dist: dist.into(),
|
||||||
|
|
@ -154,21 +158,25 @@ impl ResolutionGraph {
|
||||||
|
|
||||||
for (package, version) in selection {
|
for (package, version) in selection {
|
||||||
match package {
|
match package {
|
||||||
PubGrubPackage::Package(package_name, None, None) => {
|
PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
extra: None,
|
||||||
|
url: None,
|
||||||
|
} => {
|
||||||
// Create the distribution.
|
// Create the distribution.
|
||||||
let dist = pins
|
let dist = pins
|
||||||
.get(package_name, version)
|
.get(name, version)
|
||||||
.expect("Every package should be pinned")
|
.expect("Every package should be pinned")
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
// Extract the hashes, preserving those that were already present in the
|
// Extract the hashes, preserving those that were already present in the
|
||||||
// lockfile if necessary.
|
// lockfile if necessary.
|
||||||
let hashes = if let Some(digests) = preferences
|
let hashes = if let Some(digests) = preferences
|
||||||
.match_hashes(package_name, version)
|
.match_hashes(name, version)
|
||||||
.filter(|digests| !digests.is_empty())
|
.filter(|digests| !digests.is_empty())
|
||||||
{
|
{
|
||||||
digests.to_vec()
|
digests.to_vec()
|
||||||
} else if let Some(versions_response) = packages.get(package_name) {
|
} else if let Some(versions_response) = packages.get(name) {
|
||||||
if let VersionsResponse::Found(ref version_maps) = *versions_response {
|
if let VersionsResponse::Found(ref version_maps) = *versions_response {
|
||||||
version_maps
|
version_maps
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -187,7 +195,7 @@ impl ResolutionGraph {
|
||||||
|
|
||||||
// Extract the metadata.
|
// Extract the metadata.
|
||||||
let metadata = {
|
let metadata = {
|
||||||
let dist = PubGrubDistribution::from_registry(package_name, version);
|
let dist = PubGrubDistribution::from_registry(name, version);
|
||||||
|
|
||||||
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
let response = distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
||||||
panic!(
|
panic!(
|
||||||
|
|
@ -207,7 +215,7 @@ impl ResolutionGraph {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract the extras.
|
// Extract the extras.
|
||||||
let extras = extras.get(package_name).cloned().unwrap_or_default();
|
let extras = extras.get(name).cloned().unwrap_or_default();
|
||||||
|
|
||||||
// Add the distribution to the graph.
|
// Add the distribution to the graph.
|
||||||
let index = petgraph.add_node(AnnotatedDist {
|
let index = petgraph.add_node(AnnotatedDist {
|
||||||
|
|
@ -216,13 +224,16 @@ impl ResolutionGraph {
|
||||||
hashes,
|
hashes,
|
||||||
metadata,
|
metadata,
|
||||||
});
|
});
|
||||||
inverse.insert(package_name, index);
|
inverse.insert(name, index);
|
||||||
}
|
}
|
||||||
PubGrubPackage::Package(package_name, None, Some(url)) => {
|
PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
extra: None,
|
||||||
|
url: Some(url),
|
||||||
|
} => {
|
||||||
// Create the distribution.
|
// Create the distribution.
|
||||||
if let Some(editable) = editables.get(package_name) {
|
if let Some(editable) = editables.get(name) {
|
||||||
let dist =
|
let dist = Dist::from_editable(name.clone(), editable.built.clone())?;
|
||||||
Dist::from_editable(package_name.clone(), editable.built.clone())?;
|
|
||||||
|
|
||||||
// Add the distribution to the graph.
|
// Add the distribution to the graph.
|
||||||
let index = petgraph.add_node(AnnotatedDist {
|
let index = petgraph.add_node(AnnotatedDist {
|
||||||
|
|
@ -231,15 +242,14 @@ impl ResolutionGraph {
|
||||||
hashes: vec![],
|
hashes: vec![],
|
||||||
metadata: editable.metadata.clone(),
|
metadata: editable.metadata.clone(),
|
||||||
});
|
});
|
||||||
inverse.insert(package_name, index);
|
inverse.insert(name, index);
|
||||||
} else {
|
} else {
|
||||||
let dist =
|
let dist = Dist::from_url(name.clone(), url_to_precise(url.clone()))?;
|
||||||
Dist::from_url(package_name.clone(), url_to_precise(url.clone()))?;
|
|
||||||
|
|
||||||
// Extract the hashes, preserving those that were already present in the
|
// Extract the hashes, preserving those that were already present in the
|
||||||
// lockfile if necessary.
|
// lockfile if necessary.
|
||||||
let hashes = if let Some(digests) = preferences
|
let hashes = if let Some(digests) = preferences
|
||||||
.match_hashes(package_name, version)
|
.match_hashes(name, version)
|
||||||
.filter(|digests| !digests.is_empty())
|
.filter(|digests| !digests.is_empty())
|
||||||
{
|
{
|
||||||
digests.to_vec()
|
digests.to_vec()
|
||||||
|
|
@ -259,7 +269,7 @@ impl ResolutionGraph {
|
||||||
|
|
||||||
// Extract the metadata.
|
// Extract the metadata.
|
||||||
let metadata = {
|
let metadata = {
|
||||||
let dist = PubGrubDistribution::from_url(package_name, url);
|
let dist = PubGrubDistribution::from_url(name, url);
|
||||||
|
|
||||||
let response =
|
let response =
|
||||||
distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
distributions.get(&dist.version_id()).unwrap_or_else(|| {
|
||||||
|
|
@ -280,7 +290,7 @@ impl ResolutionGraph {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extract the extras.
|
// Extract the extras.
|
||||||
let extras = extras.get(package_name).cloned().unwrap_or_default();
|
let extras = extras.get(name).cloned().unwrap_or_default();
|
||||||
|
|
||||||
// Add the distribution to the graph.
|
// Add the distribution to the graph.
|
||||||
let index = petgraph.add_node(AnnotatedDist {
|
let index = petgraph.add_node(AnnotatedDist {
|
||||||
|
|
@ -289,7 +299,7 @@ impl ResolutionGraph {
|
||||||
hashes,
|
hashes,
|
||||||
metadata,
|
metadata,
|
||||||
});
|
});
|
||||||
inverse.insert(package_name, index);
|
inverse.insert(name, index);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -314,22 +324,28 @@ impl ResolutionGraph {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let PubGrubPackage::Package(self_package, _, _) = self_package else {
|
let PubGrubPackage::Package {
|
||||||
|
name: self_name, ..
|
||||||
|
} = self_package
|
||||||
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let PubGrubPackage::Package(dependency_package, _, _) = dependency_package
|
let PubGrubPackage::Package {
|
||||||
|
name: dependency_name,
|
||||||
|
..
|
||||||
|
} = dependency_package
|
||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// For extras, we include a dependency between the extra and the base package.
|
// For extras, we include a dependency between the extra and the base package.
|
||||||
if self_package == dependency_package {
|
if self_name == dependency_name {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self_version.contains(version) {
|
if self_version.contains(version) {
|
||||||
let self_index = &inverse[self_package];
|
let self_index = &inverse[self_name];
|
||||||
let dependency_index = &inverse[dependency_package];
|
let dependency_index = &inverse[dependency_name];
|
||||||
petgraph.update_edge(
|
petgraph.update_edge(
|
||||||
*self_index,
|
*self_index,
|
||||||
*dependency_index,
|
*dependency_index,
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,12 @@ impl BatchPrefetcher {
|
||||||
index: &InMemoryIndex,
|
index: &InMemoryIndex,
|
||||||
selector: &CandidateSelector,
|
selector: &CandidateSelector,
|
||||||
) -> anyhow::Result<(), ResolveError> {
|
) -> anyhow::Result<(), ResolveError> {
|
||||||
let PubGrubPackage::Package(package_name, None, None) = &next else {
|
let PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
extra: None,
|
||||||
|
url: None,
|
||||||
|
} = &next
|
||||||
|
else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -66,7 +71,7 @@ impl BatchPrefetcher {
|
||||||
// This is immediate, we already fetched the version map.
|
// This is immediate, we already fetched the version map.
|
||||||
let versions_response = index
|
let versions_response = index
|
||||||
.packages()
|
.packages()
|
||||||
.wait_blocking(package_name)
|
.wait_blocking(name)
|
||||||
.ok_or(ResolveError::Unregistered)?;
|
.ok_or(ResolveError::Unregistered)?;
|
||||||
|
|
||||||
let VersionsResponse::Found(ref version_map) = *versions_response else {
|
let VersionsResponse::Found(ref version_map) = *versions_response else {
|
||||||
|
|
@ -85,7 +90,7 @@ impl BatchPrefetcher {
|
||||||
previous,
|
previous,
|
||||||
} => {
|
} => {
|
||||||
if let Some(candidate) =
|
if let Some(candidate) =
|
||||||
selector.select_no_preference(package_name, &compatible, version_map)
|
selector.select_no_preference(name, &compatible, version_map)
|
||||||
{
|
{
|
||||||
let compatible = compatible.intersection(
|
let compatible = compatible.intersection(
|
||||||
&Range::singleton(candidate.version().clone()).complement(),
|
&Range::singleton(candidate.version().clone()).complement(),
|
||||||
|
|
@ -103,13 +108,13 @@ impl BatchPrefetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BatchPrefetchStrategy::InOrder { previous } => {
|
BatchPrefetchStrategy::InOrder { previous } => {
|
||||||
let range = if selector.use_highest_version(package_name) {
|
let range = if selector.use_highest_version(name) {
|
||||||
Range::strictly_lower_than(previous)
|
Range::strictly_lower_than(previous)
|
||||||
} else {
|
} else {
|
||||||
Range::strictly_higher_than(previous)
|
Range::strictly_higher_than(previous)
|
||||||
};
|
};
|
||||||
if let Some(candidate) =
|
if let Some(candidate) =
|
||||||
selector.select_no_preference(package_name, &range, version_map)
|
selector.select_no_preference(name, &range, version_map)
|
||||||
{
|
{
|
||||||
phase = BatchPrefetchStrategy::InOrder {
|
phase = BatchPrefetchStrategy::InOrder {
|
||||||
previous: candidate.version().clone(),
|
previous: candidate.version().clone(),
|
||||||
|
|
@ -148,7 +153,7 @@ impl BatchPrefetcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Prefetching {prefetch_count} {package_name} versions");
|
debug!("Prefetching {prefetch_count} {name} versions");
|
||||||
|
|
||||||
self.last_prefetch.insert(next.clone(), num_tried);
|
self.last_prefetch.insert(next.clone(), num_tried);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -157,7 +162,7 @@ impl BatchPrefetcher {
|
||||||
/// Each time we tried a version for a package, we register that here.
|
/// Each time we tried a version for a package, we register that here.
|
||||||
pub(crate) fn version_tried(&mut self, package: PubGrubPackage) {
|
pub(crate) fn version_tried(&mut self, package: PubGrubPackage) {
|
||||||
// Only track base packages, no virtual packages from extras.
|
// Only track base packages, no virtual packages from extras.
|
||||||
if matches!(package, PubGrubPackage::Package(_, Some(_), _)) {
|
if matches!(package, PubGrubPackage::Package { extra: Some(_), .. }) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*self.tried_versions.entry(package).or_default() += 1;
|
*self.tried_versions.entry(package).or_default() += 1;
|
||||||
|
|
|
||||||
|
|
@ -480,8 +480,8 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
.expect("a package was chosen but we don't have a term.");
|
.expect("a package was chosen but we don't have a term.");
|
||||||
|
|
||||||
// Check if the decision was due to the package being unavailable
|
// Check if the decision was due to the package being unavailable
|
||||||
if let PubGrubPackage::Package(ref package_name, _, _) = state.next {
|
if let PubGrubPackage::Package { ref name, .. } = state.next {
|
||||||
if let Some(entry) = self.unavailable_packages.get(package_name) {
|
if let Some(entry) = self.unavailable_packages.get(name) {
|
||||||
state
|
state
|
||||||
.pubgrub
|
.pubgrub
|
||||||
.add_incompatibility(Incompatibility::custom_term(
|
.add_incompatibility(Incompatibility::custom_term(
|
||||||
|
|
@ -636,8 +636,10 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
match package {
|
match package {
|
||||||
PubGrubPackage::Root(_) => {}
|
PubGrubPackage::Root(_) => {}
|
||||||
PubGrubPackage::Python(_) => {}
|
PubGrubPackage::Python(_) => {}
|
||||||
PubGrubPackage::Extra(_, _, _) => {}
|
PubGrubPackage::Extra { .. } => {}
|
||||||
PubGrubPackage::Package(name, _extra, None) => {
|
PubGrubPackage::Package {
|
||||||
|
name, url: None, ..
|
||||||
|
} => {
|
||||||
// Verify that the package is allowed under the hash-checking policy.
|
// Verify that the package is allowed under the hash-checking policy.
|
||||||
if !self.hasher.allows_package(name) {
|
if !self.hasher.allows_package(name) {
|
||||||
return Err(ResolveError::UnhashedPackage(name.clone()));
|
return Err(ResolveError::UnhashedPackage(name.clone()));
|
||||||
|
|
@ -648,7 +650,11 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
request_sink.blocking_send(Request::Package(name.clone()))?;
|
request_sink.blocking_send(Request::Package(name.clone()))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PubGrubPackage::Package(name, _extra, Some(url)) => {
|
PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
url: Some(url),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
// Verify that the package is allowed under the hash-checking policy.
|
// Verify that the package is allowed under the hash-checking policy.
|
||||||
if !self.hasher.allows_url(&url.verbatim) {
|
if !self.hasher.allows_url(&url.verbatim) {
|
||||||
return Err(ResolveError::UnhashedPackage(name.clone()));
|
return Err(ResolveError::UnhashedPackage(name.clone()));
|
||||||
|
|
@ -678,10 +684,15 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
// Iterate over the potential packages, and fetch file metadata for any of them. These
|
// Iterate over the potential packages, and fetch file metadata for any of them. These
|
||||||
// represent our current best guesses for the versions that we _might_ select.
|
// represent our current best guesses for the versions that we _might_ select.
|
||||||
for (package, range) in packages {
|
for (package, range) in packages {
|
||||||
let PubGrubPackage::Package(package_name, None, None) = package else {
|
let PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
extra: None,
|
||||||
|
url: None,
|
||||||
|
} = package
|
||||||
|
else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
request_sink.blocking_send(Request::Prefetch(package_name.clone(), range.clone()))?;
|
request_sink.blocking_send(Request::Prefetch(name.clone(), range.clone()))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -720,15 +731,23 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PubGrubPackage::Extra(package_name, _, Some(url))
|
PubGrubPackage::Extra {
|
||||||
| PubGrubPackage::Package(package_name, _, Some(url)) => {
|
name,
|
||||||
|
url: Some(url),
|
||||||
|
..
|
||||||
|
}
|
||||||
|
| PubGrubPackage::Package {
|
||||||
|
name,
|
||||||
|
url: Some(url),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
debug!(
|
debug!(
|
||||||
"Searching for a compatible version of {package} @ {} ({range})",
|
"Searching for a compatible version of {package} @ {} ({range})",
|
||||||
url.verbatim
|
url.verbatim
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the dist is an editable, return the version from the editable metadata.
|
// If the dist is an editable, return the version from the editable metadata.
|
||||||
if let Some(editable) = self.editables.get(package_name) {
|
if let Some(editable) = self.editables.get(name) {
|
||||||
let version = &editable.metadata.version;
|
let version = &editable.metadata.version;
|
||||||
|
|
||||||
// The version is incompatible with the requirement.
|
// The version is incompatible with the requirement.
|
||||||
|
|
@ -752,7 +771,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
return Ok(Some(ResolverVersion::Available(version.clone())));
|
return Ok(Some(ResolverVersion::Available(version.clone())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let dist = PubGrubDistribution::from_url(package_name, url);
|
let dist = PubGrubDistribution::from_url(name, url);
|
||||||
let response = self
|
let response = self
|
||||||
.index
|
.index
|
||||||
.distributions()
|
.distributions()
|
||||||
|
|
@ -764,26 +783,26 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
MetadataResponse::Found(archive) => &archive.metadata,
|
MetadataResponse::Found(archive) => &archive.metadata,
|
||||||
MetadataResponse::Offline => {
|
MetadataResponse::Offline => {
|
||||||
self.unavailable_packages
|
self.unavailable_packages
|
||||||
.insert(package_name.clone(), UnavailablePackage::Offline);
|
.insert(name.clone(), UnavailablePackage::Offline);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
MetadataResponse::InvalidMetadata(err) => {
|
||||||
self.unavailable_packages.insert(
|
self.unavailable_packages.insert(
|
||||||
package_name.clone(),
|
name.clone(),
|
||||||
UnavailablePackage::InvalidMetadata(err.to_string()),
|
UnavailablePackage::InvalidMetadata(err.to_string()),
|
||||||
);
|
);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
MetadataResponse::InconsistentMetadata(err) => {
|
MetadataResponse::InconsistentMetadata(err) => {
|
||||||
self.unavailable_packages.insert(
|
self.unavailable_packages.insert(
|
||||||
package_name.clone(),
|
name.clone(),
|
||||||
UnavailablePackage::InvalidMetadata(err.to_string()),
|
UnavailablePackage::InvalidMetadata(err.to_string()),
|
||||||
);
|
);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
MetadataResponse::InvalidStructure(err) => {
|
||||||
self.unavailable_packages.insert(
|
self.unavailable_packages.insert(
|
||||||
package_name.clone(),
|
name.clone(),
|
||||||
UnavailablePackage::InvalidStructure(err.to_string()),
|
UnavailablePackage::InvalidStructure(err.to_string()),
|
||||||
);
|
);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|
@ -813,31 +832,35 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
Ok(Some(ResolverVersion::Available(version.clone())))
|
Ok(Some(ResolverVersion::Available(version.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
PubGrubPackage::Extra(package_name, _, None)
|
PubGrubPackage::Extra {
|
||||||
| PubGrubPackage::Package(package_name, _, None) => {
|
name, url: None, ..
|
||||||
|
}
|
||||||
|
| PubGrubPackage::Package {
|
||||||
|
name, url: None, ..
|
||||||
|
} => {
|
||||||
// Wait for the metadata to be available.
|
// Wait for the metadata to be available.
|
||||||
let versions_response = self
|
let versions_response = self
|
||||||
.index
|
.index
|
||||||
.packages()
|
.packages()
|
||||||
.wait_blocking(package_name)
|
.wait_blocking(name)
|
||||||
.ok_or(ResolveError::Unregistered)?;
|
.ok_or(ResolveError::Unregistered)?;
|
||||||
visited.insert(package_name.clone());
|
visited.insert(name.clone());
|
||||||
|
|
||||||
let version_maps = match *versions_response {
|
let version_maps = match *versions_response {
|
||||||
VersionsResponse::Found(ref version_maps) => version_maps.as_slice(),
|
VersionsResponse::Found(ref version_maps) => version_maps.as_slice(),
|
||||||
VersionsResponse::NoIndex => {
|
VersionsResponse::NoIndex => {
|
||||||
self.unavailable_packages
|
self.unavailable_packages
|
||||||
.insert(package_name.clone(), UnavailablePackage::NoIndex);
|
.insert(name.clone(), UnavailablePackage::NoIndex);
|
||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
VersionsResponse::Offline => {
|
VersionsResponse::Offline => {
|
||||||
self.unavailable_packages
|
self.unavailable_packages
|
||||||
.insert(package_name.clone(), UnavailablePackage::Offline);
|
.insert(name.clone(), UnavailablePackage::Offline);
|
||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
VersionsResponse::NotFound => {
|
VersionsResponse::NotFound => {
|
||||||
self.unavailable_packages
|
self.unavailable_packages
|
||||||
.insert(package_name.clone(), UnavailablePackage::NotFound);
|
.insert(name.clone(), UnavailablePackage::NotFound);
|
||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -846,7 +869,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
|
|
||||||
// Find a version.
|
// Find a version.
|
||||||
let Some(candidate) = self.selector.select(
|
let Some(candidate) = self.selector.select(
|
||||||
package_name,
|
name,
|
||||||
range,
|
range,
|
||||||
version_maps,
|
version_maps,
|
||||||
&self.preferences,
|
&self.preferences,
|
||||||
|
|
@ -892,7 +915,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
let version = candidate.version().clone();
|
let version = candidate.version().clone();
|
||||||
|
|
||||||
// Emit a request to fetch the metadata for this version.
|
// Emit a request to fetch the metadata for this version.
|
||||||
if matches!(package, PubGrubPackage::Package(_, _, _)) {
|
if matches!(package, PubGrubPackage::Package { .. }) {
|
||||||
if self.index.distributions().register(candidate.version_id()) {
|
if self.index.distributions().register(candidate.version_id()) {
|
||||||
let request = Request::from(dist.for_resolution());
|
let request = Request::from(dist.for_resolution());
|
||||||
request_sink.blocking_send(request)?;
|
request_sink.blocking_send(request)?;
|
||||||
|
|
@ -997,16 +1020,16 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
|
|
||||||
PubGrubPackage::Python(_) => Ok(Dependencies::Available(Vec::default())),
|
PubGrubPackage::Python(_) => Ok(Dependencies::Available(Vec::default())),
|
||||||
|
|
||||||
PubGrubPackage::Package(package_name, extra, url) => {
|
PubGrubPackage::Package { name, extra, url } => {
|
||||||
// If we're excluding transitive dependencies, short-circuit.
|
// If we're excluding transitive dependencies, short-circuit.
|
||||||
if self.dependency_mode.is_direct() {
|
if self.dependency_mode.is_direct() {
|
||||||
// If an extra is provided, wait for the metadata to be available, since it's
|
// If an extra is provided, wait for the metadata to be available, since it's
|
||||||
// still required for generating the lock file.
|
// still required for generating the lock file.
|
||||||
if !self.editables.contains(package_name) {
|
if !self.editables.contains(name) {
|
||||||
// Determine the distribution to lookup.
|
// Determine the distribution to lookup.
|
||||||
let dist = match url {
|
let dist = match url {
|
||||||
Some(url) => PubGrubDistribution::from_url(package_name, url),
|
Some(url) => PubGrubDistribution::from_url(name, url),
|
||||||
None => PubGrubDistribution::from_registry(package_name, version),
|
None => PubGrubDistribution::from_registry(name, version),
|
||||||
};
|
};
|
||||||
let version_id = dist.version_id();
|
let version_id = dist.version_id();
|
||||||
|
|
||||||
|
|
@ -1021,7 +1044,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if the distribution is editable.
|
// Determine if the distribution is editable.
|
||||||
if let Some(editable) = self.editables.get(package_name) {
|
if let Some(editable) = self.editables.get(name) {
|
||||||
let requirements: Vec<_> = editable
|
let requirements: Vec<_> = editable
|
||||||
.metadata
|
.metadata
|
||||||
.requires_dist
|
.requires_dist
|
||||||
|
|
@ -1033,7 +1056,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
&requirements,
|
&requirements,
|
||||||
&self.constraints,
|
&self.constraints,
|
||||||
&self.overrides,
|
&self.overrides,
|
||||||
Some(package_name),
|
Some(name),
|
||||||
extra.as_ref(),
|
extra.as_ref(),
|
||||||
&self.urls,
|
&self.urls,
|
||||||
&self.locals,
|
&self.locals,
|
||||||
|
|
@ -1055,24 +1078,21 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
|
|
||||||
// Determine the distribution to lookup.
|
// Determine the distribution to lookup.
|
||||||
let dist = match url {
|
let dist = match url {
|
||||||
Some(url) => PubGrubDistribution::from_url(package_name, url),
|
Some(url) => PubGrubDistribution::from_url(name, url),
|
||||||
None => PubGrubDistribution::from_registry(package_name, version),
|
None => PubGrubDistribution::from_registry(name, version),
|
||||||
};
|
};
|
||||||
let version_id = dist.version_id();
|
let version_id = dist.version_id();
|
||||||
|
|
||||||
// If the package does not exist in the registry or locally, we cannot fetch its dependencies
|
// If the package does not exist in the registry or locally, we cannot fetch its dependencies
|
||||||
if self.unavailable_packages.get(package_name).is_some()
|
if self.unavailable_packages.get(name).is_some()
|
||||||
&& self
|
&& self.installed_packages.get_packages(name).is_empty()
|
||||||
.installed_packages
|
|
||||||
.get_packages(package_name)
|
|
||||||
.is_empty()
|
|
||||||
{
|
{
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
false,
|
false,
|
||||||
"Dependencies were requested for a package that is not available"
|
"Dependencies were requested for a package that is not available"
|
||||||
);
|
);
|
||||||
return Err(ResolveError::Failure(format!(
|
return Err(ResolveError::Failure(format!(
|
||||||
"The package is unavailable: {package_name}"
|
"The package is unavailable: {name}"
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1087,15 +1107,15 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
MetadataResponse::Found(archive) => &archive.metadata,
|
MetadataResponse::Found(archive) => &archive.metadata,
|
||||||
MetadataResponse::Offline => {
|
MetadataResponse::Offline => {
|
||||||
self.incomplete_packages
|
self.incomplete_packages
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(version.clone(), IncompletePackage::Offline);
|
.insert(version.clone(), IncompletePackage::Offline);
|
||||||
return Ok(Dependencies::Unavailable(UnavailableVersion::Offline));
|
return Ok(Dependencies::Unavailable(UnavailableVersion::Offline));
|
||||||
}
|
}
|
||||||
MetadataResponse::InvalidMetadata(err) => {
|
MetadataResponse::InvalidMetadata(err) => {
|
||||||
warn!("Unable to extract metadata for {package_name}: {err}");
|
warn!("Unable to extract metadata for {name}: {err}");
|
||||||
self.incomplete_packages
|
self.incomplete_packages
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(
|
.insert(
|
||||||
version.clone(),
|
version.clone(),
|
||||||
|
|
@ -1106,9 +1126,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
MetadataResponse::InconsistentMetadata(err) => {
|
MetadataResponse::InconsistentMetadata(err) => {
|
||||||
warn!("Unable to extract metadata for {package_name}: {err}");
|
warn!("Unable to extract metadata for {name}: {err}");
|
||||||
self.incomplete_packages
|
self.incomplete_packages
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(
|
.insert(
|
||||||
version.clone(),
|
version.clone(),
|
||||||
|
|
@ -1119,9 +1139,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
MetadataResponse::InvalidStructure(err) => {
|
MetadataResponse::InvalidStructure(err) => {
|
||||||
warn!("Unable to extract metadata for {package_name}: {err}");
|
warn!("Unable to extract metadata for {name}: {err}");
|
||||||
self.incomplete_packages
|
self.incomplete_packages
|
||||||
.entry(package_name.clone())
|
.entry(name.clone())
|
||||||
.or_default()
|
.or_default()
|
||||||
.insert(
|
.insert(
|
||||||
version.clone(),
|
version.clone(),
|
||||||
|
|
@ -1143,7 +1163,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
&requirements,
|
&requirements,
|
||||||
&self.constraints,
|
&self.constraints,
|
||||||
&self.overrides,
|
&self.overrides,
|
||||||
Some(package_name),
|
Some(name),
|
||||||
extra.as_ref(),
|
extra.as_ref(),
|
||||||
&self.urls,
|
&self.urls,
|
||||||
&self.locals,
|
&self.locals,
|
||||||
|
|
@ -1164,13 +1184,21 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a dependency on both the extra and base package.
|
// Add a dependency on both the extra and base package.
|
||||||
PubGrubPackage::Extra(package_name, extra, url) => Ok(Dependencies::Available(vec![
|
PubGrubPackage::Extra { name, extra, url } => Ok(Dependencies::Available(vec![
|
||||||
(
|
(
|
||||||
PubGrubPackage::Package(package_name.clone(), None, url.clone()),
|
PubGrubPackage::Package {
|
||||||
|
name: name.clone(),
|
||||||
|
extra: None,
|
||||||
|
url: url.clone(),
|
||||||
|
},
|
||||||
Range::singleton(version.clone()),
|
Range::singleton(version.clone()),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
PubGrubPackage::Package(package_name.clone(), Some(extra.clone()), url.clone()),
|
PubGrubPackage::Package {
|
||||||
|
name: name.clone(),
|
||||||
|
extra: Some(extra.clone()),
|
||||||
|
url: url.clone(),
|
||||||
|
},
|
||||||
Range::singleton(version.clone()),
|
Range::singleton(version.clone()),
|
||||||
),
|
),
|
||||||
])),
|
])),
|
||||||
|
|
@ -1398,12 +1426,18 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
||||||
match package {
|
match package {
|
||||||
PubGrubPackage::Root(_) => {}
|
PubGrubPackage::Root(_) => {}
|
||||||
PubGrubPackage::Python(_) => {}
|
PubGrubPackage::Python(_) => {}
|
||||||
PubGrubPackage::Extra(_, _, _) => {}
|
PubGrubPackage::Extra { .. } => {}
|
||||||
PubGrubPackage::Package(package_name, _extra, Some(url)) => {
|
PubGrubPackage::Package {
|
||||||
reporter.on_progress(package_name, &VersionOrUrlRef::Url(&url.verbatim));
|
name,
|
||||||
|
url: Some(url),
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
reporter.on_progress(name, &VersionOrUrlRef::Url(&url.verbatim));
|
||||||
}
|
}
|
||||||
PubGrubPackage::Package(package_name, _extra, None) => {
|
PubGrubPackage::Package {
|
||||||
reporter.on_progress(package_name, &VersionOrUrlRef::Version(version));
|
name, url: None, ..
|
||||||
|
} => {
|
||||||
|
reporter.on_progress(name, &VersionOrUrlRef::Version(version));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue