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


Reply via email to