gather-dnf: Run latest() later

The initial version of the filtered the latest builds at the start. That
doesn't matter in many cases:

* When there are no lookaside repos, there is generally a single version
  of each package.
* When lookaside repos do not overlap with compose repos, or contain
  only older versions.

It is however a problem when the lookaside repos contain higher version
of a package than what is in a compose repo, and some package explicitly
requires the older version.

Consider this scenario:

* lookaside contains bar-1.1
* compose repo contains bar-1.0 and foo-1.0
* foo-1.0 `Requires: bar < 1.1`

The original code would filter out the bar-1.0 package, and then fail on
unresolved dependencies.

This patch moves the computation of latest packages much later, to part
of code where all options to satisfy a dependency are selected and the
best match is chosen. At that point if there are multiple versions
available, we do want the latest one.

JIRA: SPMM-13483
Signed-off-by: Lubomír Sedlář <lsedlar@redhat.com>
(cherry picked from commit bcc440491e)
This commit is contained in:
Lubomír Sedlář 2023-06-05 10:35:44 +02:00 committed by Stepan Oksanichenko
parent d4425f7935
commit 44ea4d4419
Signed by: soksanichenko
GPG Key ID: AB9983172AB1E45B

View File

@ -250,7 +250,7 @@ class Gather(GatherBase):
lookaside_pkgs = set()
if self.opts.lookaside_repos:
# We called `latest()` to get the highest version packages only.
# We will call `latest()` to get the highest version packages only.
# However, that is per name and architecture. If a package switches
# from arched to noarch or the other way, it is possible that the
# package_list contains different versions in main repos and in
@ -279,9 +279,6 @@ class Gather(GatherBase):
if pkg.repoid in self.opts.lookaside_repos:
lookaside_pkgs.add("{0.name}-{0.evr}".format(pkg))
if self.opts.greedy_method == "all":
return list(package_list)
all_pkgs = []
for pkg in package_list:
# Remove packages that are also in lookaside
@ -293,16 +290,21 @@ class Gather(GatherBase):
if not debuginfo:
native_pkgs = set(
self.q_native_binary_packages.filter(pkg=all_pkgs).apply()
self.q_native_binary_packages.filter(pkg=all_pkgs).latest().apply()
)
multilib_pkgs = set(
self.q_multilib_binary_packages.filter(pkg=all_pkgs).apply()
self.q_multilib_binary_packages.filter(pkg=all_pkgs).latest().apply()
)
else:
native_pkgs = set(self.q_native_debug_packages.filter(pkg=all_pkgs).apply())
multilib_pkgs = set(
self.q_multilib_debug_packages.filter(pkg=all_pkgs).apply()
native_pkgs = set(
self.q_native_debug_packages.filter(pkg=all_pkgs).latest().apply()
)
multilib_pkgs = set(
self.q_multilib_debug_packages.filter(pkg=all_pkgs).latest().apply()
)
if self.opts.greedy_method == "all":
return list(native_pkgs | multilib_pkgs)
result = set()
@ -422,9 +424,7 @@ class Gather(GatherBase):
"""Given an name of a queue (stored as attribute in `self`), exclude
all given packages and keep only the latest per package name and arch.
"""
setattr(
self, queue, getattr(self, queue).filter(pkg__neq=exclude).latest().apply()
)
setattr(self, queue, getattr(self, queue).filter(pkg__neq=exclude).apply())
@Profiler("Gather._apply_excludes()")
def _apply_excludes(self, excludes):