From: Sebastian Luther <sebastianlut...@gmx.de> This time rebuilds are scheduled properly, but we might still forget to install the package that caused the rebuild.
URL: https://bugs.gentoo.org/486580 --- pym/_emerge/depgraph.py | 30 ++++++++++- .../tests/resolver/test_slot_conflict_rebuild.py | 63 ++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index da2e604..0f8f76d 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2356,6 +2356,18 @@ class depgraph(object): # discarded here. Try to discard as few as possible since # discarded dependencies reduce the amount of information # available for optimization of merge order. + # Don't ignore dependencies if pkg as a slot operator dependency on the child + # and the child has changed slot/sub_slot + slot_operator_rebuild = False + if atom.slot_operator == '=' and \ + (pkg.root, pkg.slot_atom) in self._dynamic_config._slot_operator_replace_installed and \ + mypriority.satisfied and \ + mypriority.satisfied is not child and \ + mypriority.satisfied.installed and \ + not child.installed and \ + (child.slot != mypriority.satisfied.slot or child.sub_slot != mypriority.satisfied.sub_slot): + slot_operator_rebuild = True + ignored = False if not atom.blocker and \ not recurse_satisfied and \ @@ -2364,7 +2376,8 @@ class depgraph(object): dep.child is not None and \ not dep.child.installed and \ self._dynamic_config._slot_pkg_map[dep.child.root].get( - dep.child.slot_atom) is None: + dep.child.slot_atom) is None and \ + not slot_operator_rebuild: myarg = None try: myarg = next(self._iter_atoms_for_pkg(dep.child), None) @@ -2466,6 +2479,18 @@ class depgraph(object): parent=virt_pkg, priority=mypriority, root=dep_root, collapsed_parent=pkg, collapsed_priority=dep_priority) + # Don't ignore dependencies if pkg as a slot operator dependency on the child + # and the child has changed slot/sub_slot + slot_operator_rebuild = False + if atom.slot_operator == '=' and \ + (pkg.root, pkg.slot_atom) in self._dynamic_config._slot_operator_replace_installed and \ + mypriority.satisfied and \ + mypriority.satisfied is not child and \ + mypriority.satisfied.installed and \ + not child.installed and \ + (child.slot != mypriority.satisfied.slot or child.sub_slot != mypriority.satisfied.sub_slot): + slot_operator_rebuild = True + ignored = False if not atom.blocker and \ not recurse_satisfied and \ @@ -2474,7 +2499,8 @@ class depgraph(object): dep.child is not None and \ not dep.child.installed and \ self._dynamic_config._slot_pkg_map[dep.child.root].get( - dep.child.slot_atom) is None: + dep.child.slot_atom) is None and \ + not slot_operator_rebuild: myarg = None try: myarg = next(self._iter_atoms_for_pkg(dep.child), None) diff --git a/pym/portage/tests/resolver/test_slot_conflict_rebuild.py b/pym/portage/tests/resolver/test_slot_conflict_rebuild.py index 74f5cc1..e3c517d 100644 --- a/pym/portage/tests/resolver/test_slot_conflict_rebuild.py +++ b/pym/portage/tests/resolver/test_slot_conflict_rebuild.py @@ -181,6 +181,69 @@ class SlotConflictRebuildTestCase(TestCase): finally: playground.cleanup() + def testSlotConflictForgottenChild(self): + """ + Similar to testSlotConflictMassRebuild above, but this time the rebuilds are scheduled, + but the package causing the rebuild (the child) is not installed. + """ + ebuilds = { + + "app-misc/A-2" : { + "EAPI": "5", + "DEPEND": "app-misc/B:= app-misc/C", + "RDEPEND": "app-misc/B:= app-misc/C", + }, + + "app-misc/B-2" : { + "EAPI": "5", + "SLOT": "2" + }, + + "app-misc/C-1": { + "EAPI": "5", + "DEPEND": "app-misc/B:=", + "RDEPEND": "app-misc/B:=" + }, + } + + installed = { + "app-misc/A-1" : { + "EAPI": "5", + "DEPEND": "app-misc/B:1/1= app-misc/C", + "RDEPEND": "app-misc/B:1/1= app-misc/C", + }, + + "app-misc/B-1" : { + "EAPI": "5", + "SLOT": "1" + }, + + "app-misc/C-1": { + "EAPI": "5", + "DEPEND": "app-misc/B:1/1=", + "RDEPEND": "app-misc/B:1/1=" + }, + } + + test_cases = ( + ResolverPlaygroundTestCase( + ["app-misc/A"], + success = True, + mergelist = ['app-misc/B-2', 'app-misc/C-1', 'app-misc/A-2']), + ) + + world = [] + + playground = ResolverPlayground(ebuilds=ebuilds, + installed=installed, world=world, debug=False) + try: + for test_case in test_cases: + playground.run_TestCase(test_case) + self.assertEqual(test_case.test_success, True, test_case.fail_msg) + finally: + playground.cleanup() + + def testSlotConflictDepChange(self): """ Bug 490362 -- 1.8.1.5