From b43adff637efe29ddafcc5d63a3e51733f5d944f Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Sat, 5 Nov 2011 10:59:37 +0100 Subject: [PATCH] [entropy.client.interfaces.dep] introduce the "Slot intersection" feature Certain dependency strings could have cross-SLOT scope (multiple slots for same package are valid) causing unwanted dependencies to be pulled in. For example: if dependency is "dev-lang/python" and we have dev-lang/python-2 installed, python-3 should be filtered out (if possible) by checking if the installed best dependency match slot is still available in repositories. If it is, restrict the dependency scope to the intersection between available SLOTs and installed SLOT. --- lib/entropy/client/interfaces/dep.py | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lib/entropy/client/interfaces/dep.py b/lib/entropy/client/interfaces/dep.py index e8c01180c..950712a4d 100644 --- a/lib/entropy/client/interfaces/dep.py +++ b/lib/entropy/client/interfaces/dep.py @@ -361,6 +361,8 @@ class CalculatorsMixin: return dbpkginfo + DISABLE_SLOT_INTERSECTION = os.getenv("ETP_DISABLE_SLOT_INTERSECTION") + def _get_unsatisfied_dependencies(self, dependencies, deep_deps = False, relaxed_deps = False, depcache = None, match_repo = None): @@ -583,6 +585,59 @@ class CalculatorsMixin: push_to_cache(dependency, False) continue + # Slot intersection support: + # certain dependency strings could have + # cross-SLOT scope (multiple slots for same package are valid) + # causing unwanted dependencies to be pulled in. + # For example: if dependency is "dev-lang/python" + # and we have dev-lang/python-2 installed, python-3 + # should be filtered out (if possible) by checking if + # the installed best dependency match slot is still + # available in repositories. + # If it is, restrict the dependency scope to the intersection + # between available SLOTs and installed SLOT. + multi_repo = False + if match_repo is None: + multi_repo = True + + available_slots = set() + if not self.DISABLE_SLOT_INTERSECTION: + r_matches, r_rcs = self.atom_match( + dependency, match_repo = match_repo, + multi_match = True, multi_repo = multi_repo) + available_slots |= set(self.open_repository(x[1]).retrieveSlot( + x[0]) for x in r_matches) + if len(available_slots) > 1: + # more than one slot available + # pick the best one by calling atomMatch() without multiMatch + c_id, c_rc = self._installed_repository.atomMatch( + dependency) + installed_slot = None + if c_id != -1: + installed_slot = self._installed_repository.retrieveSlot( + c_id) + if installed_slot in available_slots: + # restrict my matching to installed_slot, rewrite + # r_id r_repo + old_r_id = r_id + old_r_repo = r_repo + r_id, r_repo = self.atom_match( + dependency, match_slot = installed_slot) + if const_debug_enabled(): + from_atom = self.open_repository( + old_r_repo).retrieveAtom(old_r_id) + to_atom = self.open_repository( + r_repo).retrieveAtom(r_id) + const_debug_write( + __name__, + "_get_unsatisfied_dependencies " + " SLOT intersection: installed: " + "%s, available: %s, from: %s [%s], to: %s [%s]" % ( + installed_slot, available_slots, + (old_r_id, old_r_repo), + from_atom, (r_id, r_repo), + to_atom,)) + # satisfied dependencies filter support # package.satisfied file support if (r_id, r_repo,) in satisfied_data: