[flatpak] sorting packages before updating

This commit is contained in:
Vinícius Moreira
2020-02-06 19:40:14 -03:00
parent 44ad20f613
commit ecd936c6fd
9 changed files with 171 additions and 21 deletions

View File

@@ -79,21 +79,21 @@ class AURClient:
self.logger.info('{p} is based on {b}. Retrieving {b} .SRCINFO'.format(p=info_name, b=info_base))
return self.get_src_info(info_base)
def extract_all_dependencies(self, pkginfo: dict) -> Set[str]:
def extract_required_dependencies(self, pkginfo: dict) -> Set[str]:
deps = set()
for attr in ('makedepends', 'depends', 'checkdepends'):
if pkginfo.get(attr):
deps.update([pacman.RE_DEP_OPERATORS.split(dep)[0] for dep in info[attr]])
deps.update([pacman.RE_DEP_OPERATORS.split(dep)[0] for dep in pkginfo[attr]])
return deps
def get_all_dependencies(self, name: str) -> Set[str]:
def get_required_dependencies(self, name: str) -> Set[str]:
info = self.get_src_info(name)
if not info:
raise PackageNotFoundException(name)
return self.extract_all_dependencies(info)
return self.extract_required_dependencies(info)
def _map_names_as_queries(self, names) -> str:
return '&'.join(['arg[{}]={}'.format(i, urllib.parse.quote(n)) for i, n in enumerate(names)])

View File

@@ -1009,7 +1009,7 @@ class ArchManager(SoftwareManager):
for n in names:
names_map[n] = pkg
pkg_deps[pkg] = self.aur_client.extract_all_dependencies(srcinfo)
pkg_deps[pkg] = self.aur_client.extract_required_dependencies(srcinfo)
except:
pkg_deps[pkg] = None
self.logger.warning("Could not retrieve dependencies for '{}'".format(pkg.name))

View File

@@ -71,7 +71,7 @@ class DependenciesAnalyser:
missing_sub = []
for rdep in missing_root:
subdeps = self.aur_client.get_all_dependencies(rdep[0]) if rdep[1] == 'aur' else pacman.read_dependencies(rdep[0])
subdeps = self.aur_client.get_required_dependencies(rdep[0]) if rdep[1] == 'aur' else pacman.read_dependencies(rdep[0])
subdeps_not_analysis = {sd for sd in subdeps if sd not in global_in_analysis}
if subdeps_not_analysis:
@@ -93,7 +93,7 @@ class DependenciesAnalyser:
in_analyses = {*names}
for name in names:
subdeps = self.aur_client.get_all_dependencies(name) if mirror == 'aur' else pacman.read_dependencies(name)
subdeps = self.aur_client.get_required_dependencies(name) if mirror == 'aur' else pacman.read_dependencies(name)
if subdeps:
missing_subdeps = self.get_missing_packages(subdeps, in_analysis=in_analyses)

View File

@@ -469,3 +469,28 @@ class FlatpakManager(SoftwareManager):
except:
return False, [traceback.format_exc()]
def sort_update_order(self, pkgs: List[FlatpakApplication]) -> List[FlatpakApplication]:
partials, runtimes, apps = [], [], []
for p in pkgs:
if p.runtime:
if p.partial:
partials.append(p)
else:
runtimes.append(p)
else:
apps.append(p)
if not runtimes:
return [*partials, *apps]
elif partials:
all_runtimes = []
for runtime in runtimes:
for partial in partials:
if partial.base_id == runtime.id:
all_runtimes.append(partial)
all_runtimes.append(runtime)
return [*all_runtimes, *apps]
else:
return [*runtimes, *apps]

View File

@@ -10,7 +10,7 @@ class FlatpakApplication(SoftwarePackage):
def __init__(self, id: str = None, name: str = None, version: str = None, latest_version: str = None, description: str = None,
branch: str = None, arch: str = None, origin: str = None, runtime: bool = False, ref: str = None, commit: str = None,
installation: str = None, i18n: I18n = None):
installation: str = None, i18n: I18n = None, partial: bool = False):
super(FlatpakApplication, self).__init__(id=id, name=name, version=version,
latest_version=latest_version, description=description)
self.ref = ref
@@ -19,7 +19,7 @@ class FlatpakApplication(SoftwarePackage):
self.origin = origin
self.runtime = runtime
self.commit = commit
self.partial = False
self.partial = partial
self.installation = installation if installation else 'system'
self.i18n = i18n
self.base_id = None

View File

@@ -438,9 +438,13 @@ class GenericSoftwareManager(SoftwareManager):
if by_manager:
for man, pkgs in by_manager.items():
ti = time.time()
sorted_list.extend(man.sort_update_order(pkgs))
tf = time.time()
self.logger.info(man.__class__.__name__ + " took {0:.2f} seconds".format(tf - ti))
if len(pkgs) > 1:
ti = time.time()
sorted_list.extend(man.sort_update_order(pkgs))
tf = time.time()
self.logger.info(man.__class__.__name__ + " took {0:.2f} seconds".format(tf - ti))
else:
self.logger.info("Only one package to sort for {}. Ignoring sorting.".format(man.__class__.__name__))
sorted_list.extend(pkgs)
return sorted_list

View File

@@ -108,7 +108,7 @@ class UpdateSelectedApps(AsyncAction):
sorted_pkgs = self.manager.sort_update_order([view.model for view in self.apps_to_update])
for pkg in sorted_pkgs:
self.change_substatus('')
name = pkg.name if not RE_VERSION_IN_NAME.findall(pkg.name) else pkg.name.split('version')[0].strip()
self.change_status('{} {} {}...'.format(self.i18n['manage_window.status.upgrading'], name, pkg.version))

View File

@@ -13,7 +13,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='kazam', package_base='kazam'): {'python', 'python-cairo'}
}
sorted_list = ArchManager._sort_deps(deps, {d.name: d.name for d in deps})
sorted_list = ArchManager._sort_deps(deps, {d.name: d for d in deps})
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(deps), len(sorted_list))
@@ -26,7 +26,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='abc', package_base='abc'): None
}
sorted_list = ArchManager._sort_deps(deps, {d.name: d.name for d in deps})
sorted_list = ArchManager._sort_deps(deps, {d.name: d for d in deps})
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(deps), len(sorted_list))
@@ -40,7 +40,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='ghi', package_base='ghi'): {}
}
name_map = {d.name: d.name for d in deps}
name_map = {d.name: d for d in deps}
for _ in range(5): # testing n times to see if the same result is produced
sorted_list = ArchManager._sort_deps(deps, name_map)
self.assertIsInstance(sorted_list, list)
@@ -71,7 +71,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='ghi', package_base='ghi'): {'def'}
}
name_map = {d.name: d.name for d in deps}
name_map = {d.name: d for d in deps}
for _ in range(5): # testing n times to see if the same result is produced
sorted_list = ArchManager._sort_deps(deps, name_map)
self.assertIsInstance(sorted_list, list)
@@ -101,7 +101,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='jkl', package_base='jkl'): {'ghi'}
}
name_map = {d.name: d.name for d in deps}
name_map = {d.name: d for d in deps}
for _ in range(5): # testing n times to see if the same result is produced
sorted_list = ArchManager._sort_deps(deps, name_map)
self.assertIsInstance(sorted_list, list)
@@ -129,7 +129,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='jkl', package_base='jkl'): {'abc'}
}
sorted_list = ArchManager._sort_deps(deps, {d.name: d.name for d in deps})
sorted_list = ArchManager._sort_deps(deps, {d.name: d for d in deps})
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(deps), len(sorted_list))
@@ -152,7 +152,7 @@ class ArchManagerSortUpdateOrderTest(TestCase):
ArchPackage(name='ghi', package_base='ghi'): {'abc'}
}
name_map = {d.name: d.name for d in deps}
name_map = {d.name: d for d in deps}
name_map['fed'] = def_pkg
for _ in range(5):

View File

@@ -0,0 +1,121 @@
from unittest import TestCase
from unittest.mock import Mock
from bauh.gems.flatpak.controller import FlatpakManager
from bauh.gems.flatpak.model import FlatpakApplication
class FlatpakManagerSortUpdateOrderTest(TestCase):
def setUp(self):
self.manager = FlatpakManager(Mock())
def test__sort_deps__only_apps(self):
pkgs = [
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
FlatpakApplication(id="com.spotify.Client", name='com.spotify.Client', runtime=False),
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
for pkg in sorted_list:
self.assertIn(pkg, pkgs)
def test__sort_deps__one_app_one_runtime(self):
pkgs = [
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
FlatpakApplication(id="org.gnome.Platform", name='org.gnome.Platform', runtime=True),
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
self.assertEqual(pkgs[1], sorted_list[0])
self.assertEqual(pkgs[0], sorted_list[1])
def test__sort_deps__two_apps_one_runtime(self):
pkgs = [
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
FlatpakApplication(id="org.gnome.Platform", name='org.gnome.Platform', runtime=True),
FlatpakApplication(id="com.spotify.Client", name='com.spotify.Client', runtime=False)
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
self.assertEqual(pkgs[1], sorted_list[0])
self.assertEqual(pkgs[0], sorted_list[1])
self.assertEqual(pkgs[2], sorted_list[2])
def test_sort_deps_two_apps_two_runtimes(self):
pkgs = [
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
FlatpakApplication(id="org.gnome.Platform", name='Platform', runtime=True),
FlatpakApplication(id="com.spotify.Client", name='Spotify', runtime=False),
FlatpakApplication(id="org.freedesktop.Platform.GL.default", name='default', runtime=True)
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
self.assertEqual(pkgs[1], sorted_list[0])
self.assertEqual(pkgs[3], sorted_list[1])
self.assertEqual(pkgs[0], sorted_list[2])
self.assertEqual(pkgs[2], sorted_list[3])
def test_sort_deps_two_apps_two_runtimes_one_partial(self):
gnome_platform = FlatpakApplication(id="org.gnome.Platform", name='Platform', runtime=True)
gnome_locale = FlatpakApplication(id="org.gnome.Platform.Locale", name="Locale", runtime=True, partial=True)
gnome_locale.base_id = gnome_platform.id
pkgs = [
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
gnome_platform,
FlatpakApplication(id="com.spotify.Client", name='Spotify', runtime=False),
FlatpakApplication(id="org.freedesktop.Platform.GL.default", name='default', runtime=True),
gnome_locale
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
self.assertEqual(pkgs[4], sorted_list[0])
self.assertEqual(pkgs[1], sorted_list[1])
self.assertEqual(pkgs[3], sorted_list[2])
self.assertEqual(pkgs[0], sorted_list[3])
self.assertEqual(pkgs[2], sorted_list[4])
def test_sort_deps_two_apps_two_runtimes_two_partials(self):
gnome_platform = FlatpakApplication(id="org.gnome.Platform", name='Platform', runtime=True)
gnome_locale = FlatpakApplication(id="org.gnome.Platform.Locale", name="Locale", runtime=True, partial=True)
gnome_locale.base_id = gnome_platform.id
platform_default = FlatpakApplication(id="org.freedesktop.Platform.GL.default", name='default', runtime=True)
platform_locale = FlatpakApplication(id="org.freedesktop.Platform.GL.Locale", name='Locale', runtime=True, partial=True)
platform_locale.base_id = platform_default.id
pkgs = [
platform_locale,
FlatpakApplication(id="org.gnome.gedit", name='Gedit', runtime=False),
gnome_platform,
FlatpakApplication(id="com.spotify.Client", name='Spotify', runtime=False),
platform_default,
gnome_locale
]
sorted_list = self.manager.sort_update_order(pkgs)
self.assertIsInstance(sorted_list, list)
self.assertEqual(len(pkgs), len(sorted_list))
self.assertEqual(gnome_locale.id, sorted_list[0].id)
self.assertEqual(gnome_platform.id, sorted_list[1].id)
self.assertEqual(platform_locale.id, sorted_list[2].id)
self.assertEqual(platform_default.id, sorted_list[3].id)
self.assertEqual('org.gnome.gedit', sorted_list[4].id)
self.assertEqual('com.spotify.Client', sorted_list[5].id)