From 44ad20f613569367a8da1e3f47364ae86fa204c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Wed, 5 Feb 2020 19:29:05 -0300 Subject: [PATCH] [aur] supporting right sort when the package provides multiple names --- bauh/gems/arch/aur.py | 15 +++++++----- bauh/gems/arch/controller.py | 41 +++++++++++++++++++++++-------- tests/gems/arch/controller.py | 46 +++++++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/bauh/gems/arch/aur.py b/bauh/gems/arch/aur.py index 111025f3..ae951c30 100644 --- a/bauh/gems/arch/aur.py +++ b/bauh/gems/arch/aur.py @@ -79,18 +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 get_all_dependencies(self, name: str) -> Set[str]: + def extract_all_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]]) + + return deps + + def get_all_dependencies(self, name: str) -> Set[str]: info = self.get_src_info(name) if not info: raise PackageNotFoundException(name) - for attr in ('makedepends', 'depends', 'checkdepends'): - if info.get(attr): - deps.update([pacman.RE_DEP_OPERATORS.split(dep)[0] for dep in info[attr]]) - - return deps + return self.extract_all_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 c7195895..8f3397c3 100644 --- a/bauh/gems/arch/controller.py +++ b/bauh/gems/arch/controller.py @@ -995,12 +995,21 @@ class ArchManager(SoftwareManager): return False, [traceback.format_exc()] def sort_update_order(self, pkgs: List[ArchPackage]) -> List[ArchPackage]: - # TODO pegar o 'provides' dos pacotes ? - pkg_deps = {} + pkg_deps = {} # maps the package instance and a set with all its dependencies + names_map = {} # maps all the package provided names to the package instance def _add_info(pkg: ArchPackage): try: - pkg_deps[pkg] = self.aur_client.get_all_dependencies(pkg.name) + srcinfo = self.aur_client.get_src_info(pkg.name) + + names_map[pkg.name] = pkg + names = srcinfo.get('pkgname') + + if isinstance(names, list): + for n in names: + names_map[n] = pkg + + pkg_deps[pkg] = self.aur_client.extract_all_dependencies(srcinfo) except: pkg_deps[pkg] = None self.logger.warning("Could not retrieve dependencies for '{}'".format(pkg.name)) @@ -1015,10 +1024,10 @@ class ArchManager(SoftwareManager): for t in threads: t.join() - return self._sort_deps(pkg_deps) + return self._sort_deps(pkg_deps, names_map) @classmethod - def _sort_deps(cls, pkg_deps: Dict[ArchPackage, Set[str]]) -> List[ArchPackage]: + def _sort_deps(cls, pkg_deps: Dict[ArchPackage, Set[str]], names_map: Dict[str, ArchPackage]) -> List[ArchPackage]: sorted_names, not_sorted = {}, {} pkg_map = {} @@ -1033,13 +1042,13 @@ class ArchManager(SoftwareManager): # now adding all that depends on another: for name, pkg in not_sorted.items(): - cls._add_to_sort(pkg, pkg_deps, sorted_names, not_sorted) + cls._add_to_sort(pkg, pkg_deps, sorted_names, not_sorted, names_map) position_map = {'{}-{}'.format(i, n): pkg_map[n] for n, i in sorted_names.items()} return [position_map[idx] for idx in sorted(position_map)] @classmethod - def _add_to_sort(cls, pkg: ArchPackage, pkg_deps: Dict[ArchPackage, Set[str]], sorted_names: Dict[str, int], not_sorted: Dict[str, ArchPackage]) -> int: + def _add_to_sort(cls, pkg: ArchPackage, pkg_deps: Dict[ArchPackage, Set[str]], sorted_names: Dict[str, int], not_sorted: Dict[str, ArchPackage], names_map: Dict[str, ArchPackage]) -> int: idx = sorted_names.get(pkg.name) if idx is not None: @@ -1053,9 +1062,21 @@ class ArchManager(SoftwareManager): if dep_idx is not None: idx = dep_idx + 1 - elif dep in not_sorted: # it means the dep is one of the packages to sort, but it not sorted yet - dep_idx = cls._add_to_sort(not_sorted[dep], pkg_deps, sorted_names, not_sorted) - idx = dep_idx + 1 + else: + dep_pkg = names_map.get(dep) + + if dep_pkg: # it means the declared dep is mapped differently from the provided packages to update + dep_idx = sorted_names.get(dep_pkg.name) + + if dep_idx is not None: + idx = dep_idx + 1 + else: + dep_idx = cls._add_to_sort(dep_pkg, pkg_deps, sorted_names, not_sorted, names_map) + idx = dep_idx + 1 + + elif dep in not_sorted: # it means the dep is one of the packages to sort, but it not sorted yet + dep_idx = cls._add_to_sort(not_sorted[dep], pkg_deps, sorted_names, not_sorted, names_map) + idx = dep_idx + 1 sorted_names[pkg.name] = idx diff --git a/tests/gems/arch/controller.py b/tests/gems/arch/controller.py index 09fd521f..0dd69bb7 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) + sorted_list = ArchManager._sort_deps(deps, {d.name: d.name 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) + sorted_list = ArchManager._sort_deps(deps, {d.name: d.name for d in deps}) self.assertIsInstance(sorted_list, list) self.assertEqual(len(deps), len(sorted_list)) @@ -40,8 +40,9 @@ class ArchManagerSortUpdateOrderTest(TestCase): ArchPackage(name='ghi', package_base='ghi'): {} } + name_map = {d.name: d.name 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) + sorted_list = ArchManager._sort_deps(deps, name_map) self.assertIsInstance(sorted_list, list) self.assertEqual(len(deps), len(sorted_list)) @@ -70,8 +71,9 @@ class ArchManagerSortUpdateOrderTest(TestCase): ArchPackage(name='ghi', package_base='ghi'): {'def'} } + name_map = {d.name: d.name 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) + sorted_list = ArchManager._sort_deps(deps, name_map) self.assertIsInstance(sorted_list, list) self.assertEqual(len(deps), len(sorted_list)) @@ -99,8 +101,9 @@ class ArchManagerSortUpdateOrderTest(TestCase): ArchPackage(name='jkl', package_base='jkl'): {'ghi'} } + name_map = {d.name: d.name 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) + sorted_list = ArchManager._sort_deps(deps, name_map) self.assertIsInstance(sorted_list, list) self.assertEqual(len(deps), len(sorted_list)) @@ -118,7 +121,6 @@ class ArchManagerSortUpdateOrderTest(TestCase): """ dep order: abc -> def -> ghi -> jkl -> abc - expected: """ deps = { ArchPackage(name='abc', package_base='abc'): {'def'}, @@ -127,7 +129,7 @@ class ArchManagerSortUpdateOrderTest(TestCase): ArchPackage(name='jkl', package_base='jkl'): {'abc'} } - sorted_list = ArchManager._sort_deps(deps) + sorted_list = ArchManager._sort_deps(deps, {d.name: d.name for d in deps}) self.assertIsInstance(sorted_list, list) self.assertEqual(len(deps), len(sorted_list)) @@ -135,4 +137,32 @@ class ArchManagerSortUpdateOrderTest(TestCase): self.assertIn(pkg, deps) def test__sort_deps__a_declared_dep_provided_as_a_different_name(self): - pass + """ + dep order: + abc -> fed + def (fed) + ghi -> abc + expected: def, abc, ghi + """ + def_pkg = ArchPackage(name='def', package_base='def') + + deps = { + ArchPackage(name='abc', package_base='abc'): {'fed'}, + def_pkg: {}, + ArchPackage(name='ghi', package_base='ghi'): {'abc'} + } + + name_map = {d.name: d.name for d in deps} + name_map['fed'] = def_pkg + + for _ in range(5): + sorted_list = ArchManager._sort_deps(deps, name_map) + self.assertIsInstance(sorted_list, list) + self.assertEqual(len(deps), len(sorted_list)) + + for pkg in sorted_list: + self.assertIn(pkg, deps) + + self.assertEqual(sorted_list[0].name, 'def') + self.assertEqual(sorted_list[1].name, 'abc') + self.assertEqual(sorted_list[2].name, 'ghi')