Skip to content

Commit 44ffaf1

Browse files
committed
backends/eopkg: Rework __get_package() to employ a candidates system
There has been a long standing fixme to fix this function to return multiple candidates if needed that required hacks elsewhere for proper filtering behaviour, most notably for the newest filter Rework this function to emit candidates and well as employ proper package release comparison such that the newest filter works correctly in all instances.
1 parent c2f7eb8 commit 44ffaf1

1 file changed

Lines changed: 80 additions & 66 deletions

File tree

backends/eopkg/eopkgBackend.py

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -334,76 +334,96 @@ def __get_package(self, package, filters=None):
334334
if installed is None and available is None:
335335
raise PkError(ERROR_PACKAGE_NOT_FOUND, "Package %s not found" % package)
336336

337-
pkg = None
338-
status = None
339-
data = None
337+
# We will collect candidate packages here: (pkg, status, data)
338+
candidates = []
339+
340+
# Check if we have any status filters
341+
status_filters = [FILTER_INSTALLED, FILTER_NOT_INSTALLED, FILTER_NEWEST]
342+
has_status_filter = filters and any(f in status_filters for f in filters)
340343

341-
if filters is not None:
344+
if has_status_filter:
342345
if FILTER_INSTALLED in filters:
343346
if installed:
344-
pkg = installed
345-
status = INFO_INSTALLED
346347
data = "installed:{}".format(repo) if repo else "installed"
347-
else:
348-
return
348+
candidates.append((installed, INFO_INSTALLED, data))
349349
elif FILTER_NOT_INSTALLED in filters:
350350
if available:
351-
pkg = available
352-
status = INFO_AVAILABLE
353-
data = repo
354-
else:
355-
return
351+
candidates.append((available, INFO_AVAILABLE, repo))
356352
elif FILTER_NEWEST in filters:
357-
if available:
358-
pkg = available
359-
status = INFO_AVAILABLE
360-
data = repo
361-
elif installed:
362-
pkg = installed
363-
status = INFO_INSTALLED
364-
data = "installed"
365-
else:
366-
return
353+
if installed and available:
354+
# Compare versions/releases
355+
v_inst = self.installdb.get_version_and_distro_release(package)
356+
v_avail = self.packagedb.get_version_and_distro_release(
357+
package, repo
358+
)
367359

368-
# Fallback if no filter matched or no filters provided
369-
if pkg is None:
360+
# (version, release, build, distro, distro_release)
361+
# If version is different, we should probably compare versions.
362+
# But if they are the same, release comparison is sufficient.
363+
# In Solus/eopkg, release is the primary versioning for updates.
364+
if v_inst[0] == v_avail[0]:
365+
if int(v_avail[1]) > int(v_inst[1]):
366+
candidates.append((available, INFO_AVAILABLE, repo))
367+
elif int(v_avail[1]) == int(v_inst[1]):
368+
# Same version, show both
369+
data = "installed:{}".format(repo) if repo else "installed"
370+
candidates.append((installed, INFO_INSTALLED, data))
371+
candidates.append((available, INFO_AVAILABLE, repo))
372+
else:
373+
# Installed is newer
374+
data = "installed:{}".format(repo) if repo else "installed"
375+
candidates.append((installed, INFO_INSTALLED, data))
376+
else:
377+
# Versions differ, we'd need a version comparison tool here.
378+
# For now, if versions differ, we'll just show both or available
379+
# if it looks newer (e.g. higher release).
380+
# Most often, version is the same.
381+
if int(v_avail[1]) > int(v_inst[1]):
382+
candidates.append((available, INFO_AVAILABLE, repo))
383+
else:
384+
data = "installed:{}".format(repo) if repo else "installed"
385+
candidates.append((installed, INFO_INSTALLED, data))
386+
elif available:
387+
candidates.append((available, INFO_AVAILABLE, repo))
388+
elif installed:
389+
candidates.append((installed, INFO_INSTALLED, "installed"))
390+
else:
391+
# No status filters, show both if they exist
370392
if installed:
371-
pkg = installed
372-
status = INFO_INSTALLED
373393
data = "installed:{}".format(repo) if repo else "installed"
374-
else:
375-
pkg = available
376-
status = INFO_AVAILABLE
377-
data = repo
394+
candidates.append((installed, INFO_INSTALLED, data))
395+
if available:
396+
candidates.append((available, INFO_AVAILABLE, repo))
378397

379-
if filters is not None:
380-
if FILTER_GUI in filters and "app:gui" not in pkg.isA:
381-
return
382-
if FILTER_NOT_GUI in filters and "app:gui" in pkg.isA:
383-
return
384-
# FIXME: To lower
385-
nonfree = ["EULA", "Distributable"]
386-
if FILTER_FREE in filters:
387-
if any(l in pkg.license for l in nonfree):
388-
return
389-
if FILTER_NOT_FREE in filters:
390-
if not any(l in pkg.license for l in nonfree):
391-
return
392-
if FILTER_DEVELOPMENT in filters and "-devel" not in pkg.name:
393-
return
394-
if FILTER_NOT_DEVELOPMENT in filters and "-devel" in pkg.name:
395-
return
396-
pkg_subtypes = ["-devel", "-dbginfo", "-32bit", "-docs"]
397-
if FILTER_BASENAME in filters:
398-
if any(suffix in pkg.name for suffix in pkg_subtypes):
399-
return
400-
if FILTER_NOT_BASENAME in filters:
401-
if not any(suffix in pkg.name for suffix in pkg_subtypes):
402-
return
403-
404-
version = self.__get_package_version(pkg)
405-
id = self.get_package_id(pkg.name, version, pkg.architecture, data)
406-
return self.package(id, status, pkg.summary)
398+
for pkg, status, data in candidates:
399+
if filters is not None:
400+
if FILTER_GUI in filters and "app:gui" not in pkg.isA:
401+
continue
402+
if FILTER_NOT_GUI in filters and "app:gui" in pkg.isA:
403+
continue
404+
# FIXME: To lower
405+
nonfree = ["EULA", "Distributable"]
406+
if FILTER_FREE in filters:
407+
if any(l in pkg.license for l in nonfree):
408+
continue
409+
if FILTER_NOT_FREE in filters:
410+
if not any(l in pkg.license for l in nonfree):
411+
continue
412+
if FILTER_DEVELOPMENT in filters and "-devel" not in pkg.name:
413+
continue
414+
if FILTER_NOT_DEVELOPMENT in filters and "-devel" in pkg.name:
415+
continue
416+
pkg_subtypes = ["-devel", "-dbginfo", "-32bit", "-docs"]
417+
if FILTER_BASENAME in filters:
418+
if any(suffix in pkg.name for suffix in pkg_subtypes):
419+
continue
420+
if FILTER_NOT_BASENAME in filters:
421+
if not any(suffix in pkg.name for suffix in pkg_subtypes):
422+
continue
423+
424+
version = self.__get_package_version(pkg)
425+
pkg_id = self.get_package_id(pkg.name, version, pkg.architecture, data)
426+
self.package(pkg_id, status, pkg.summary)
407427

408428
def depends_on(self, filters, package_ids, recursive):
409429
"""Prints a list of depends for a given package"""
@@ -983,13 +1003,7 @@ def resolve(self, filters, values):
9831003
for package in values:
9841004
name = self.get_package_from_id(package)[0]
9851005
try:
986-
if filters is not None:
987-
self.__get_package(name, filters)
988-
else:
989-
# If no filters, show both installed and available if they exist
990-
# we should really fix __get_package to allow emitting multiple results
991-
self.__get_package(name, [FILTER_INSTALLED])
992-
self.__get_package(name, [FILTER_NOT_INSTALLED])
1006+
self.__get_package(name, filters)
9931007
except PkError as e:
9941008
if e.code == ERROR_PACKAGE_NOT_FOUND:
9951009
continue

0 commit comments

Comments
 (0)