diff --git a/bauh/gems/arch/aur.py b/bauh/gems/arch/aur.py index ae951c30..82daa77b 100644 --- a/bauh/gems/arch/aur.py +++ b/bauh/gems/arch/aur.py @@ -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)]) diff --git a/bauh/gems/arch/controller.py b/bauh/gems/arch/controller.py index 8f3397c3..73c6a477 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -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)) diff --git a/bauh/gems/arch/depedencies.py b/bauh/gems/arch/depedencies.py index 5d67a7c2..170d8ade 100644 --- a/bauh/gems/arch/depedencies.py +++ b/bauh/gems/arch/depedencies.py @@ -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) diff --git a/bauh/gems/flatpak/controller.py b/bauh/gems/flatpak/controller.py index c1fee9dc..c8927c6a 100644 --- a/bauh/gems/flatpak/controller.py +++ b/bauh/gems/flatpak/controller.py @@ -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] diff --git a/bauh/gems/flatpak/model.py b/bauh/gems/flatpak/model.py index ae70d4ec..38f17508 100644 --- a/bauh/gems/flatpak/model.py +++ b/bauh/gems/flatpak/model.py @@ -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 diff --git a/bauh/view/core/controller.py b/bauh/view/core/controller.py index 5048b9bb..5f23bf27 100755 --- a/bauh/view/core/controller.py +++ b/bauh/view/core/controller.py @@ -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 diff --git a/bauh/view/qt/thread.py b/bauh/view/qt/thread.py index 5813a3ff..343ec842 100644 --- a/bauh/view/qt/thread.py +++ b/bauh/view/qt/thread.py @@ -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)) diff --git a/tests/gems/arch/controller.py b/tests/gems/arch/controller.py index 0dd69bb7..1642fbc3 100644 --- a/tests/gems/arch/controller.py +++ b/tests/gems/arch/controller.py @@ -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): diff --git a/tests/gems/flatpak/controller.py b/tests/gems/flatpak/controller.py new file mode 100644 index 00000000..cd7749ca --- /dev/null +++ b/tests/gems/flatpak/controller.py @@ -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)