From 1984ada57c5331614495d6195f320210bd9277e5 Mon Sep 17 00:00:00 2001 From: konsti Date: Mon, 24 Jun 2024 19:14:09 +0200 Subject: [PATCH] Break `PubGrubReportFormatter::hints` into methods (#4478) I have to add yet another indentation level to the prerelease-available check in `PubGrubReportFormatter::hints` for #4435, so i've broken the code into methods and decreased indentation in this split out refactoring-only change. --- crates/uv-resolver/src/pubgrub/report.rs | 328 ++++++++++++----------- 1 file changed, 177 insertions(+), 151 deletions(-) diff --git a/crates/uv-resolver/src/pubgrub/report.rs b/crates/uv-resolver/src/pubgrub/report.rs index 73791b0b21c5..a416bcd797e6 100644 --- a/crates/uv-resolver/src/pubgrub/report.rs +++ b/crates/uv-resolver/src/pubgrub/report.rs @@ -410,164 +410,59 @@ impl PubGrubReportFormatter<'_> { ) -> IndexSet { let mut hints = IndexSet::default(); match derivation_tree { - DerivationTree::External(external) => match external { - External::Custom(package, set, _) | External::NoVersions(package, set) => { - if let PubGrubPackageInner::Package { - name, url: None, .. - } = &**package - { - // Check for no versions due to pre-release options. - if let Some(selector) = selector { - let any_prerelease = set.iter().any(|(start, end)| { - let is_pre1 = match start { - Bound::Included(version) => version.any_prerelease(), - Bound::Excluded(version) => version.any_prerelease(), - Bound::Unbounded => false, - }; - let is_pre2 = match end { - Bound::Included(version) => version.any_prerelease(), - Bound::Excluded(version) => version.any_prerelease(), - Bound::Unbounded => false, - }; - is_pre1 || is_pre2 - }); - - if any_prerelease { - // A pre-release marker appeared in the version requirements. - if !selector.prerelease_strategy().allows(name) { - hints.insert(PubGrubHint::PreReleaseRequested { - package: package.clone(), - range: self.simplify_set(set, package).into_owned(), - }); - } - } else if let Some(version) = - self.available_versions.get(package).and_then(|versions| { - versions - .iter() - .rev() - .filter(|version| version.any_prerelease()) - .find(|version| set.contains(version)) - }) - { - // There are pre-release versions available for the package. - if !selector.prerelease_strategy().allows(name) { - hints.insert(PubGrubHint::PreReleaseAvailable { - package: package.clone(), - version: version.clone(), - }); - } - } - } + DerivationTree::External( + External::Custom(package, set, _) | External::NoVersions(package, set), + ) => { + if let PubGrubPackageInner::Package { + name, url: None, .. + } = &**package + { + // Check for no versions due to pre-release options. + if let Some(selector) = selector { + self.prerelease_available_hint(package, name, set, selector, &mut hints); } + } - if let PubGrubPackageInner::Package { name, .. } = &**package { - // Check for no versions due to no `--find-links` flat index - if let Some(index_locations) = index_locations { - let no_find_links = - index_locations.flat_index().peekable().peek().is_none(); - - // Add hints due to the package being entirely unavailable. - match unavailable_packages.get(name) { - Some(UnavailablePackage::NoIndex) => { - if no_find_links { - hints.insert(PubGrubHint::NoIndex); - } - } - Some(UnavailablePackage::Offline) => { - hints.insert(PubGrubHint::Offline); - } - Some(UnavailablePackage::MissingMetadata) => { - hints.insert(PubGrubHint::MissingPackageMetadata { - package: package.clone(), - }); - } - Some(UnavailablePackage::InvalidMetadata(reason)) => { - hints.insert(PubGrubHint::InvalidPackageMetadata { - package: package.clone(), - reason: reason.clone(), - }); - } - Some(UnavailablePackage::InvalidStructure(reason)) => { - hints.insert(PubGrubHint::InvalidPackageStructure { - package: package.clone(), - reason: reason.clone(), - }); - } - Some(UnavailablePackage::NotFound) => {} - None => {} - } - - // Add hints due to the package being unavailable at specific versions. - if let Some(versions) = incomplete_packages.get(name) { - for (version, incomplete) in versions.iter().rev() { - if set.contains(version) { - match incomplete { - IncompletePackage::Offline => { - hints.insert(PubGrubHint::Offline); - } - IncompletePackage::MissingMetadata => { - hints.insert(PubGrubHint::MissingVersionMetadata { - package: package.clone(), - version: version.clone(), - }); - } - IncompletePackage::InvalidMetadata(reason) => { - hints.insert(PubGrubHint::InvalidVersionMetadata { - package: package.clone(), - version: version.clone(), - reason: reason.clone(), - }); - } - IncompletePackage::InconsistentMetadata(reason) => { - hints.insert( - PubGrubHint::InconsistentVersionMetadata { - package: package.clone(), - version: version.clone(), - reason: reason.clone(), - }, - ); - } - IncompletePackage::InvalidStructure(reason) => { - hints.insert( - PubGrubHint::InvalidVersionStructure { - package: package.clone(), - version: version.clone(), - reason: reason.clone(), - }, - ); - } - } - break; - } - } - } - } + if let PubGrubPackageInner::Package { name, .. } = &**package { + // Check for no versions due to no `--find-links` flat index + if let Some(index_locations) = index_locations { + Self::index_hints( + package, + name, + set, + index_locations, + unavailable_packages, + incomplete_packages, + &mut hints, + ); } } - External::FromDependencyOf(package, package_set, dependency, dependency_set) => { - // Check for no versions due to `Requires-Python`. - if matches!( - &**dependency, - PubGrubPackageInner::Python(PubGrubPython::Target) - ) { - if let Some(python) = self.python_requirement { - if let Some(PythonTarget::RequiresPython(requires_python)) = - python.target() - { - hints.insert(PubGrubHint::RequiresPython { - requires_python: requires_python.clone(), - package: package.clone(), - package_set: self - .simplify_set(package_set, package) - .into_owned(), - package_requires_python: dependency_set.clone(), - }); - } + } + DerivationTree::External(External::FromDependencyOf( + package, + package_set, + dependency, + dependency_set, + )) => { + // Check for no versions due to `Requires-Python`. + if matches!( + &**dependency, + PubGrubPackageInner::Python(PubGrubPython::Target) + ) { + if let Some(python) = self.python_requirement { + if let Some(PythonTarget::RequiresPython(requires_python)) = python.target() + { + hints.insert(PubGrubHint::RequiresPython { + requires_python: requires_python.clone(), + package: package.clone(), + package_set: self.simplify_set(package_set, package).into_owned(), + package_requires_python: dependency_set.clone(), + }); } } } - External::NotRoot(..) => {} - }, + } + DerivationTree::External(External::NotRoot(..)) => {} DerivationTree::Derived(derived) => { hints.extend(self.hints( &derived.cause1, @@ -587,6 +482,137 @@ impl PubGrubReportFormatter<'_> { } hints } + + fn index_hints( + package: &PubGrubPackage, + name: &PackageName, + set: &Range, + index_locations: &IndexLocations, + unavailable_packages: &FxHashMap, + incomplete_packages: &FxHashMap>, + hints: &mut IndexSet, + ) { + let no_find_links = index_locations.flat_index().peekable().peek().is_none(); + + // Add hints due to the package being entirely unavailable. + match unavailable_packages.get(name) { + Some(UnavailablePackage::NoIndex) => { + if no_find_links { + hints.insert(PubGrubHint::NoIndex); + } + } + Some(UnavailablePackage::Offline) => { + hints.insert(PubGrubHint::Offline); + } + Some(UnavailablePackage::MissingMetadata) => { + hints.insert(PubGrubHint::MissingPackageMetadata { + package: package.clone(), + }); + } + Some(UnavailablePackage::InvalidMetadata(reason)) => { + hints.insert(PubGrubHint::InvalidPackageMetadata { + package: package.clone(), + reason: reason.clone(), + }); + } + Some(UnavailablePackage::InvalidStructure(reason)) => { + hints.insert(PubGrubHint::InvalidPackageStructure { + package: package.clone(), + reason: reason.clone(), + }); + } + Some(UnavailablePackage::NotFound) => {} + None => {} + } + + // Add hints due to the package being unavailable at specific versions. + if let Some(versions) = incomplete_packages.get(name) { + for (version, incomplete) in versions.iter().rev() { + if set.contains(version) { + match incomplete { + IncompletePackage::Offline => { + hints.insert(PubGrubHint::Offline); + } + IncompletePackage::MissingMetadata => { + hints.insert(PubGrubHint::MissingVersionMetadata { + package: package.clone(), + version: version.clone(), + }); + } + IncompletePackage::InvalidMetadata(reason) => { + hints.insert(PubGrubHint::InvalidVersionMetadata { + package: package.clone(), + version: version.clone(), + reason: reason.clone(), + }); + } + IncompletePackage::InconsistentMetadata(reason) => { + hints.insert(PubGrubHint::InconsistentVersionMetadata { + package: package.clone(), + version: version.clone(), + reason: reason.clone(), + }); + } + IncompletePackage::InvalidStructure(reason) => { + hints.insert(PubGrubHint::InvalidVersionStructure { + package: package.clone(), + version: version.clone(), + reason: reason.clone(), + }); + } + } + break; + } + } + } + } + + fn prerelease_available_hint( + &self, + package: &PubGrubPackage, + name: &PackageName, + set: &Range, + selector: &CandidateSelector, + hints: &mut IndexSet, + ) { + let any_prerelease = set.iter().any(|(start, end)| { + let is_pre1 = match start { + Bound::Included(version) => version.any_prerelease(), + Bound::Excluded(version) => version.any_prerelease(), + Bound::Unbounded => false, + }; + let is_pre2 = match end { + Bound::Included(version) => version.any_prerelease(), + Bound::Excluded(version) => version.any_prerelease(), + Bound::Unbounded => false, + }; + is_pre1 || is_pre2 + }); + + if any_prerelease { + // A pre-release marker appeared in the version requirements. + if !selector.prerelease_strategy().allows(name) { + hints.insert(PubGrubHint::PreReleaseRequested { + package: package.clone(), + range: self.simplify_set(set, package).into_owned(), + }); + } + } else if let Some(version) = self.available_versions.get(package).and_then(|versions| { + versions + .iter() + .rev() + .filter(|version| version.any_prerelease()) + .find(|version| set.contains(version)) + }) { + // There are pre-release versions available for the package. + if !selector.prerelease_strategy().allows(name) { + hints.insert(PubGrubHint::PreReleaseAvailable { + package: package.clone(), + version: version.clone(), + }); + } + } + } } #[derive(Derivative, Debug, Clone)]