Skip to content

Commit

Permalink
Break PubGrubReportFormatter::hints into methods (#4478)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
konstin authored Jun 24, 2024
1 parent c127632 commit 1984ada
Showing 1 changed file with 177 additions and 151 deletions.
328 changes: 177 additions & 151 deletions crates/uv-resolver/src/pubgrub/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,164 +410,59 @@ impl PubGrubReportFormatter<'_> {
) -> IndexSet<PubGrubHint> {
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,
Expand All @@ -587,6 +482,137 @@ impl PubGrubReportFormatter<'_> {
}
hints
}

fn index_hints(
package: &PubGrubPackage,
name: &PackageName,
set: &Range<Version>,
index_locations: &IndexLocations,
unavailable_packages: &FxHashMap<PackageName, UnavailablePackage>,
incomplete_packages: &FxHashMap<PackageName, BTreeMap<Version, IncompletePackage>>,
hints: &mut IndexSet<PubGrubHint>,
) {
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<Version>,
selector: &CandidateSelector,
hints: &mut IndexSet<PubGrubHint>,
) {
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)]
Expand Down

0 comments on commit 1984ada

Please sign in to comment.