move: respect EAPI wrt dots_in_PN, bug #426476
authorZac Medico <zmedico@gentoo.org>
Tue, 17 Jul 2012 23:52:48 +0000 (16:52 -0700)
committerZac Medico <zmedico@gentoo.org>
Tue, 17 Jul 2012 23:52:48 +0000 (16:52 -0700)
pym/portage/dbapi/bintree.py
pym/portage/dbapi/vartree.py
pym/portage/tests/update/test_update_dbentry.py [new file with mode: 0644]
pym/portage/update.py

index e3de50f08ec0b763e0237b67fa690fe01f3b78cf..8072542e8102cc2edf7c67db1e3193c26d31904b 100644 (file)
@@ -8,6 +8,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.checksum:hashfunc_map,perform_multiple_checksums,verify_all',
        'portage.dbapi.dep_expand:dep_expand',
        'portage.dep:dep_getkey,isjustname,match_from_list',
+       'portage.eapi:_get_eapi_attrs',
        'portage.output:EOutput,colorize',
        'portage.locks:lockfile,unlockfile',
        'portage.package.ebuild.fetch:_check_distfile,_hide_url_passwd',
@@ -386,8 +387,10 @@ class binarytree(object):
                                # Ignore PROVIDE virtual match.
                                continue
                        if repo_match is not None \
-                               and not repo_match(self.dbapi.aux_get(mycpv,
-                                       ['repository'])[0]):
+                               and not repo_match(mycpv.repo):
+                               continue
+                       eapi_attrs = _get_eapi_attrs(mycpv.eapi)
+                       if not eapi_attrs.dots_in_PN and "." in catsplit(newcp)[1]:
                                continue
                        mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
                        myoldpkg = catsplit(mycpv)[1]
index 264790a032e9d35ad7f8818332fa9a76c6e7d899..0ae7dc54be26561e5e804a7c7b1b7ccd5998c575 100644 (file)
@@ -330,7 +330,10 @@ class vardbapi(dbapi):
                                # Ignore PROVIDE virtual match.
                                continue
                        if repo_match is not None \
-                               and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
+                               and not repo_match(mycpv.repo):
+                               continue
+                       eapi_attrs = _get_eapi_attrs(mycpv.eapi)
+                       if not eapi_attrs.dots_in_PN and "." in catsplit(newcp)[1]:
                                continue
                        mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
                        mynewcat = catsplit(newcp)[0]
diff --git a/pym/portage/tests/update/test_update_dbentry.py b/pym/portage/tests/update/test_update_dbentry.py
new file mode 100644 (file)
index 0000000..e13cfed
--- /dev/null
@@ -0,0 +1,184 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import re
+import textwrap
+
+import portage
+from portage import os
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import ResolverPlayground
+from portage.util import ensure_dirs
+from portage._global_updates import _do_global_updates
+
+class UpdateDbentryTestCase(TestCase):
+
+       def testUpdateDbentryTestCase(self):
+
+               ebuilds = {
+
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+                       "dev-libs/B-2::dont_apply_updates" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+               }
+
+               installed = {
+
+                       "dev-libs/A-1::test_repo" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+                       "dev-libs/B-1::test_repo" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4-python",
+                       },
+
+                       "dev-libs/M-1::test_repo" : {
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/N-1::test_repo" : {
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/N-2::test_repo" : {
+                               "EAPI": "4-python",
+                       },
+
+               }
+
+               binpkgs = {
+
+                       "dev-libs/A-1::test_repo" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+                       "dev-libs/B-1::test_repo" : {
+                               "RDEPEND" : "dev-libs/M dev-libs/N dev-libs/P",
+                               "EAPI": "4-python",
+                       },
+
+               }
+
+               world = ["dev-libs/M", "dev-libs/N"]
+
+               updates = textwrap.dedent("""
+                       move dev-libs/M dev-libs/M-moved
+                       move dev-libs/N dev-libs/N.moved
+               """)
+
+               playground = ResolverPlayground(binpkgs=binpkgs,
+                       ebuilds=ebuilds, installed=installed, world=world)
+
+               settings = playground.settings
+               trees = playground.trees
+               eroot = settings["EROOT"]
+               portdir = settings["PORTDIR"]
+               portdb = trees[eroot]["porttree"].dbapi
+               vardb = trees[eroot]["vartree"].dbapi
+               bindb = trees[eroot]["bintree"].dbapi
+               setconfig = trees[eroot]["root_config"].setconfig
+               selected_set = setconfig.getSets()["selected"]
+
+               updates_dir = os.path.join(portdir, "profiles", "updates")
+
+               try:
+                       ensure_dirs(updates_dir)
+                       with open(os.path.join(updates_dir, "1Q-2010"), 'w') as f:
+                               f.write(updates)
+
+                       # Create an empty updates directory, so that this
+                       # repo doesn't inherit updates from the main repo.
+                       ensure_dirs(os.path.join(
+                               portdb.getRepositoryPath("dont_apply_updates"),
+                               "profiles", "updates"))
+
+                       global_noiselimit = portage.util.noiselimit
+                       portage.util.noiselimit = -2
+                       try:
+                               _do_global_updates(trees, {})
+                       finally:
+                               portage.util.noiselimit = global_noiselimit
+
+                       # Workaround for cache validation not working
+                       # correctly when filesystem has timestamp precision
+                       # of 1 second.
+                       vardb._clear_cache()
+
+                       # M -> M-moved
+                       old_pattern = re.compile(r"\bdev-libs/M(\s|$)")
+                       rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/M-moved" in rdepend)
+                       rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/M-moved" in rdepend)
+                       rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/M-moved" in rdepend)
+                       rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/M-moved" in rdepend)
+
+                       # EAPI 4-python N -> N.moved
+                       rdepend = vardb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+                       old_pattern = re.compile(r"\bdev-libs/N(\s|$)")
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/N.moved" in rdepend)
+                       rdepend = bindb.aux_get("dev-libs/B-1", ["RDEPEND"])[0]
+                       self.assertTrue(old_pattern.search(rdepend) is None)
+                       self.assertTrue("dev-libs/N.moved" in rdepend)
+                       self.assertRaises(KeyError,
+                               vardb.aux_get, "dev-libs/N-2", ["EAPI"])
+                       vardb.aux_get("dev-libs/N.moved-2", ["RDEPEND"])[0]
+
+                       # EAPI 4 does not allow dots in package names for N -> N.moved
+                       rdepend = vardb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+                       self.assertTrue("dev-libs/N" in rdepend)
+                       self.assertTrue("dev-libs/N.moved" not in rdepend)
+                       rdepend = bindb.aux_get("dev-libs/A-1", ["RDEPEND"])[0]
+                       self.assertTrue("dev-libs/N" in rdepend)
+                       self.assertTrue("dev-libs/N.moved" not in rdepend)
+                       vardb.aux_get("dev-libs/N-1", ["RDEPEND"])[0]
+                       self.assertRaises(KeyError,
+                               vardb.aux_get, "dev-libs/N.moved-1", ["EAPI"])
+
+                       # dont_apply_updates
+                       rdepend = vardb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+                       self.assertTrue("dev-libs/M" in rdepend)
+                       self.assertTrue("dev-libs/M-moved" not in rdepend)
+                       rdepend = bindb.aux_get("dev-libs/A-2", ["RDEPEND"])[0]
+                       self.assertTrue("dev-libs/M" in rdepend)
+                       self.assertTrue("dev-libs/M-moved" not in rdepend)
+
+                       selected_set.load()
+                       self.assertTrue("dev-libs/M" not in selected_set)
+                       self.assertTrue("dev-libs/M-moved" in selected_set)
+                       self.assertTrue("dev-libs/N" not in selected_set)
+                       self.assertTrue("dev-libs/N.moved" in selected_set)
+
+               finally:
+                       playground.cleanup()
index a66c60b9a0cdbfd1c793445a90c5b94f28d1b85e..c9c2af99986b302e0582086369761ed3a9ac3884 100644 (file)
@@ -18,7 +18,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util:ConfigProtect,new_protect_filename,' + \
                'normalize_path,write_atomic,writemsg',
        'portage.util.listdir:_ignorecvs_dirs',
-       'portage.versions:ververify'
+       'portage.versions:catsplit,ververify'
 )
 
 from portage.const import USER_CONFIG_PATH
@@ -29,14 +29,20 @@ from portage.localization import _
 
 if sys.hexversion >= 0x3000000:
        long = int
+       _unicode = str
+else:
+       _unicode = unicode
 
 ignored_dbentries = ("CONTENTS", "environment.bz2")
 
 def update_dbentry(update_cmd, mycontent, eapi=None):
+       eapi_attrs = _get_eapi_attrs(eapi)
        if update_cmd[0] == "move":
-               old_value = str(update_cmd[1])
-               if old_value in mycontent:
-                       new_value = str(update_cmd[2])
+               avoid_dots_in_PN = (not eapi_attrs.dots_in_PN and
+                       "." in catsplit(update_cmd[2].cp)[1])
+               if not avoid_dots_in_PN and _unicode(update_cmd[1]) in mycontent:
+                       old_value = _unicode(update_cmd[1])
+                       new_value = _unicode(update_cmd[2])
                        old_value = re.escape(old_value);
                        mycontent = re.sub(old_value+"(:|$|\\s)", new_value+"\\1", mycontent)
                        def myreplace(matchobj):