When disjunctive dependencies are queued, group together disjunctions from the same dependency string so that any overlap between them will trigger expansion to DNF.
Bug: https://bugs.gentoo.org/701996 Signed-off-by: Zac Medico <zmed...@gentoo.org> --- lib/_emerge/depgraph.py | 8 +++- .../test_virtual_minimize_children.py | 39 +++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py index f80b077bc..78226a3ea 100644 --- a/lib/_emerge/depgraph.py +++ b/lib/_emerge/depgraph.py @@ -3850,10 +3850,11 @@ class depgraph(object): Yields non-disjunctive deps. Raises InvalidDependString when necessary. """ + disjunctions = [] for x in dep_struct: if isinstance(x, list): if x and x[0] == "||": - self._queue_disjunction(pkg, dep_root, dep_priority, [x]) + disjunctions.append(x) else: for y in self._queue_disjunctive_deps( pkg, dep_root, dep_priority, x): @@ -3863,10 +3864,13 @@ class depgraph(object): # or whatever other metadata gets implemented for this # purpose. if x.cp.startswith('virtual/'): - self._queue_disjunction(pkg, dep_root, dep_priority, [x]) + disjunctions.append(x) else: yield x + if disjunctions: + self._queue_disjunction(pkg, dep_root, dep_priority, disjunctions) + def _queue_disjunction(self, pkg, dep_root, dep_priority, dep_struct): self._dynamic_config._dep_disjunctive_stack.append( (pkg, dep_root, dep_priority, dep_struct)) diff --git a/lib/portage/tests/resolver/test_virtual_minimize_children.py b/lib/portage/tests/resolver/test_virtual_minimize_children.py index b566cb592..720fbe57b 100644 --- a/lib/portage/tests/resolver/test_virtual_minimize_children.py +++ b/lib/portage/tests/resolver/test_virtual_minimize_children.py @@ -285,3 +285,42 @@ class VirtualMinimizeChildrenTestCase(TestCase): finally: playground.debug = False playground.cleanup() + + + def testVirtualWine(self): + ebuilds = { + 'virtual/wine-0-r6': { + 'RDEPEND': '|| ( app-emulation/wine-staging app-emulation/wine-any ) ' + '|| ( app-emulation/wine-vanilla app-emulation/wine-staging app-emulation/wine-any )' + }, + 'app-emulation/wine-staging-4': {}, + 'app-emulation/wine-any-4': {}, + 'app-emulation/wine-vanilla-4': {}, + } + + test_cases = ( + # Test bug 701996, where separate disjunctions where not + # converted to DNF, causing both wine-vanilla and + # wine-staging to be pulled in. + ResolverPlaygroundTestCase( + [ + 'virtual/wine', + ], + success=True, + mergelist=( + 'app-emulation/wine-staging-4', + 'virtual/wine-0-r6', + ), + ), + ) + + playground = ResolverPlayground(debug=False, ebuilds=ebuilds) + + 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.debug = False + playground.cleanup() -- 2.21.0