depgraph: pull in new-style virtuals more
authorZac Medico <zmedico@gentoo.org>
Fri, 30 Sep 2011 08:30:00 +0000 (01:30 -0700)
committerZac Medico <zmedico@gentoo.org>
Fri, 30 Sep 2011 08:30:00 +0000 (01:30 -0700)
This causes new-style virtuals to get pulled in for virtuals that are
already satisfied by installed old-style virtuals. This case is common,
due to PROVIDE being (removed without revision bump) from lots of
ebuilds.

pym/_emerge/depgraph.py
pym/portage/tests/resolver/ResolverPlayground.py
pym/portage/tests/resolver/test_virtual_transition.py [new file with mode: 0644]

index da61709e74c3b456d2586b937ede3cacc9e20318..9638ce9a7ba7c28908ba83c7508913f2020ad107 100644 (file)
@@ -3953,6 +3953,12 @@ class depgraph(object):
                                                e_pkg = self._dynamic_config._slot_pkg_map[root].get(pkg.slot_atom)
                                                if not e_pkg:
                                                        break
+
+                                               if e_pkg.cp != atom_cp and \
+                                                       self._have_new_virt(root, atom_cp):
+                                                       # pull in a new-style virtual instead
+                                                       break
+
                                                # Use PackageSet.findAtomForPackage()
                                                # for PROVIDE support.
                                                if atom_set.findAtomForPackage(e_pkg, modified_use=self._pkg_use_enabled(e_pkg)):
index a73f63253467d74044d573e9f8a9d9715488c8d0..9630008b2c55c1ad1171839f0659e87c9c248694 100644 (file)
@@ -142,6 +142,7 @@ class ResolverPlayground(object):
                        homepage = metadata.pop("HOMEPAGE", None)
                        src_uri = metadata.pop("SRC_URI", None)
                        iuse = metadata.pop("IUSE", "")
+                       provide = metadata.pop("PROVIDE", None)
                        depend = metadata.pop("DEPEND", "")
                        rdepend = metadata.pop("RDEPEND", None)
                        pdepend = metadata.pop("PDEPEND", None)
@@ -174,6 +175,8 @@ class ResolverPlayground(object):
                        f.write('SLOT="' + str(slot) + '"\n')
                        f.write('KEYWORDS="' + str(keywords) + '"\n')
                        f.write('IUSE="' + str(iuse) + '"\n')
+                       if provide is not None:
+                               f.write('PROVIDE="%s"\n' % provide)
                        f.write('DEPEND="' + str(depend) + '"\n')
                        if rdepend is not None:
                                f.write('RDEPEND="' + str(rdepend) + '"\n')
@@ -224,6 +227,7 @@ class ResolverPlayground(object):
                        keywords = metadata.pop("KEYWORDS", "~x86")
                        iuse = metadata.pop("IUSE", "")
                        use = metadata.pop("USE", "")
+                       provide = metadata.pop("PROVIDE", None)
                        depend = metadata.pop("DEPEND", "")
                        rdepend = metadata.pop("RDEPEND", None)
                        pdepend = metadata.pop("PDEPEND", None)
@@ -248,6 +252,8 @@ class ResolverPlayground(object):
                        write_key("KEYWORDS", keywords)
                        write_key("IUSE", iuse)
                        write_key("USE", use)
+                       if provide is not None:
+                               write_key("PROVIDE", provide)
                        write_key("DEPEND", depend)
                        if rdepend is not None:
                                write_key("RDEPEND", rdepend)
diff --git a/pym/portage/tests/resolver/test_virtual_transition.py b/pym/portage/tests/resolver/test_virtual_transition.py
new file mode 100644 (file)
index 0000000..3f4171e
--- /dev/null
@@ -0,0 +1,51 @@
+# Copyright 2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import (ResolverPlayground,
+       ResolverPlaygroundTestCase)
+
+class VirtualTransitionTestCase(TestCase):
+
+       def testVirtualTransition(self):
+               ebuilds = {
+                       "kde-base/kcron-4.7.1" : {"RDEPEND": "virtual/cron" },
+                       "sys-process/vixie-cron-4.1-r11": {},
+                       "virtual/cron-0" : {"RDEPEND": "sys-process/vixie-cron" },
+               }
+               installed = {
+                       "kde-base/kcron-4.7.1" : {"RDEPEND": "virtual/cron" },
+                       "sys-process/vixie-cron-4.1-r11" : {"PROVIDE" : "virtual/cron"},
+               }
+
+               world = ["kde-base/kcron", "sys-process/vixie-cron"]
+
+               test_cases = (
+
+                       # Pull in a new-style virtual, even though there is an installed
+                       # old-style virtual to satisfy the virtual/cron dep. This case
+                       # is common, due to PROVIDE being removed (without revision bump)
+                       # from lots of ebuilds.
+                       ResolverPlaygroundTestCase(
+                               ["@world"],
+                               options = {"--update": True, "--deep": True},
+                               success = True,
+                               mergelist = ["virtual/cron-0"]),
+
+                       # Make sure that depclean is satisfied with the installed
+                       # old-style virutal.
+                       ResolverPlaygroundTestCase(
+                               [],
+                               options = {"--depclean": True},
+                               success = True,
+                               cleanlist = []),
+               )
+
+               playground = ResolverPlayground(ebuilds=ebuilds,
+                       installed=installed, world=world)
+               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()