Propagate EAPI for update_dbentry (bug #426476).
authorZac Medico <zmedico@gentoo.org>
Tue, 17 Jul 2012 22:21:04 +0000 (15:21 -0700)
committerZac Medico <zmedico@gentoo.org>
Tue, 17 Jul 2012 22:21:04 +0000 (15:21 -0700)
bin/emaint
pym/_emerge/FakeVartree.py
pym/portage/dbapi/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/vartree.py
pym/portage/tests/update/test_move_ent.py [new file with mode: 0644]
pym/portage/update.py
pym/portage/versions.py

index 5f54f6af5690f6835456af9e9e1b0d4e15ed5876..21604511b3a831b389118de7684a3548aa8531f0 100755 (executable)
@@ -335,12 +335,12 @@ class MoveHandler(object):
                cpv_all.sort()
                maxval = len(cpv_all)
                aux_update = self._tree.dbapi.aux_update
-               meta_keys = self._update_keys + ['repository']
-               from portage.update import update_dbentries
+               meta_keys = self._update_keys + ['repository', 'EAPI']
                if onProgress:
                        onProgress(maxval, 0)
                for i, cpv in enumerate(cpv_all):
                        metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
+                       eapi = metadata.pop('EAPI')
                        repository = metadata.pop('repository')
                        try:
                                updates = allupdates[repository]
@@ -351,7 +351,8 @@ class MoveHandler(object):
                                        continue
                        if not updates:
                                continue
-                       metadata_updates = update_dbentries(updates, metadata)
+                       metadata_updates = \
+                               portage.update_dbentries(updates, metadata, eapi=eapi)
                        if metadata_updates:
                                errors.append("'%s' has outdated metadata" % cpv)
                        if onProgress:
index e6205854097b1b6111306b30224ca115517b937c..ce15f5a36fe0c5399619192b8c9c43d7c8d1cbc9 100644 (file)
@@ -286,8 +286,9 @@ def grab_global_updates(portdb):
        return retupdates
 
 def perform_global_updates(mycpv, mydb, myupdates):
-       aux_keys = ["DEPEND", "RDEPEND", "PDEPEND", 'repository']
+       aux_keys = ["DEPEND", "EAPI", "RDEPEND", "PDEPEND", 'repository']
        aux_dict = dict(zip(aux_keys, mydb.aux_get(mycpv, aux_keys)))
+       eapi = aux_dict.pop('EAPI')
        repository = aux_dict.pop('repository')
        try:
                mycommands = myupdates[repository]
@@ -300,6 +301,6 @@ def perform_global_updates(mycpv, mydb, myupdates):
        if not mycommands:
                return
 
-       updates = update_dbentries(mycommands, aux_dict)
+       updates = update_dbentries(mycommands, aux_dict, eapi=eapi)
        if updates:
                mydb.aux_update(mycpv, updates)
index ac8d31169858b1ac262578bd7f7044a4f3a28603..b999fb5dfbacd5641ffc4e42f164a853d5a64770 100644 (file)
@@ -275,17 +275,17 @@ class dbapi(object):
                maxval = len(cpv_all)
                aux_get = self.aux_get
                aux_update = self.aux_update
-               meta_keys = ["DEPEND", "RDEPEND", "PDEPEND", "PROVIDE", 'repository']
+               meta_keys = ["DEPEND", "EAPI", "RDEPEND", "PDEPEND", "PROVIDE", 'repository']
                repo_dict = None
                if isinstance(updates, dict):
                        repo_dict = updates
-               from portage.update import update_dbentries
                if onUpdate:
                        onUpdate(maxval, 0)
                if onProgress:
                        onProgress(maxval, 0)
                for i, cpv in enumerate(cpv_all):
                        metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
+                       eapi = metadata.pop('EAPI')
                        repo = metadata.pop('repository')
                        if repo_dict is None:
                                updates_list = updates
@@ -301,7 +301,8 @@ class dbapi(object):
                        if not updates_list:
                                continue
 
-                       metadata_updates = update_dbentries(updates_list, metadata)
+                       metadata_updates = \
+                               portage.update_dbentries(updates_list, metadata, eapi=eapi)
                        if metadata_updates:
                                aux_update(cpv, metadata_updates)
                                if onUpdate:
index 1048cc108f222793b7d4ca60649de644f0a2eb9a..e3de50f08ec0b763e0237b67fa690fe01f3b78cf 100644 (file)
@@ -377,6 +377,10 @@ class binarytree(object):
                if not origmatches:
                        return moves
                for mycpv in origmatches:
+                       try:
+                               mycpv = self.dbapi._pkg_str(mycpv, None)
+                       except (KeyError, InvalidData):
+                               continue
                        mycpv_cp = portage.cpv_getkey(mycpv)
                        if mycpv_cp != origcp:
                                # Ignore PROVIDE virtual match.
@@ -404,7 +408,7 @@ class binarytree(object):
                        moves += 1
                        mytbz2 = portage.xpak.tbz2(tbz2path)
                        mydata = mytbz2.get_data()
-                       updated_items = update_dbentries([mylist], mydata)
+                       updated_items = update_dbentries([mylist], mydata, eapi=mycpv.eapi)
                        mydata.update(updated_items)
                        mydata[b'PF'] = \
                                _unicode_encode(mynewpkg + "\n",
index dddc094d24975042ad556afe41db86497d3e8a95..264790a032e9d35ad7f8818332fa9a76c6e7d899 100644 (file)
@@ -321,6 +321,10 @@ class vardbapi(dbapi):
                if not origmatches:
                        return moves
                for mycpv in origmatches:
+                       try:
+                               mycpv = self._pkg_str(mycpv, None)
+                       except (KeyError, InvalidData):
+                               continue
                        mycpv_cp = cpv_getkey(mycpv)
                        if mycpv_cp != origcp:
                                # Ignore PROVIDE virtual match.
@@ -358,7 +362,7 @@ class vardbapi(dbapi):
                                        del e
                        write_atomic(os.path.join(newpath, "PF"), new_pf+"\n")
                        write_atomic(os.path.join(newpath, "CATEGORY"), mynewcat+"\n")
-                       fixdbentries([mylist], newpath)
+                       fixdbentries([mylist], newpath, eapi=mycpv.eapi)
                return moves
 
        def cp_list(self, mycp, use_cache=1):
diff --git a/pym/portage/tests/update/test_move_ent.py b/pym/portage/tests/update/test_move_ent.py
new file mode 100644 (file)
index 0000000..716a89d
--- /dev/null
@@ -0,0 +1,109 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+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 MoveEntTestCase(TestCase):
+
+       def testMoveEnt(self):
+
+               ebuilds = {
+       
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+               }
+
+               installed = {
+
+                       "dev-libs/A-1::test_repo" : {
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+               }
+
+               binpkgs = {
+       
+                       "dev-libs/A-1::test_repo" : {
+                               "EAPI": "4",
+                       },
+
+                       "dev-libs/A-2::dont_apply_updates" : {
+                               "EAPI": "4",
+                               "SLOT": "2",
+                       },
+
+               }
+
+               updates = textwrap.dedent("""
+                       move dev-libs/A dev-libs/A-moved
+               """)
+
+               playground = ResolverPlayground(binpkgs=binpkgs,
+                       ebuilds=ebuilds, installed=installed)
+
+               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
+
+               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()
+
+                       # A -> A-moved
+                       self.assertRaises(KeyError,
+                               vardb.aux_get, "dev-libs/A-1", ["EAPI"])
+                       vardb.aux_get("dev-libs/A-moved-1", ["EAPI"])
+                       self.assertRaises(KeyError,
+                               bindb.aux_get, "dev-libs/A-1", ["EAPI"])
+                       bindb.aux_get("dev-libs/A-moved-1", ["EAPI"])
+
+                       # dont_apply_updates
+                       self.assertRaises(KeyError,
+                               vardb.aux_get, "dev-libs/A-moved-2", ["EAPI"])
+                       vardb.aux_get("dev-libs/A-2", ["EAPI"])
+                       self.assertRaises(KeyError,
+                               bindb.aux_get, "dev-libs/A-moved-2", ["EAPI"])
+                       bindb.aux_get("dev-libs/A-2", ["EAPI"])
+
+               finally:
+                       playground.cleanup()
index a5cb92edada054695131d6661a3a2c810ee99f38..a66c60b9a0cdbfd1c793445a90c5b94f28d1b85e 100644 (file)
@@ -58,7 +58,7 @@ def update_dbentry(update_cmd, mycontent, eapi=None):
                        mycontent = re.sub(old_value+"($|\\s)", new_value+"\\1", mycontent)
        return mycontent
 
-def update_dbentries(update_iter, mydata):
+def update_dbentries(update_iter, mydata, eapi=None):
        """Performs update commands and returns a
        dict containing only the updated items."""
        updated_items = {}
@@ -72,7 +72,7 @@ def update_dbentries(update_iter, mydata):
                        is_encoded = mycontent is not orig_content
                        orig_content = mycontent
                        for update_cmd in update_iter:
-                               mycontent = update_dbentry(update_cmd, mycontent)
+                               mycontent = update_dbentry(update_cmd, mycontent, eapi=eapi)
                        if mycontent != orig_content:
                                if is_encoded:
                                        mycontent = _unicode_encode(mycontent,
@@ -81,7 +81,7 @@ def update_dbentries(update_iter, mydata):
                                updated_items[k] = mycontent
        return updated_items
 
-def fixdbentries(update_iter, dbdir):
+def fixdbentries(update_iter, dbdir, eapi=None):
        """Performs update commands which result in search and replace operations
        for each of the files in dbdir (excluding CONTENTS and environment.bz2).
        Returns True when actual modifications are necessary and False otherwise."""
@@ -93,7 +93,7 @@ def fixdbentries(update_iter, dbdir):
                        mode='r', encoding=_encodings['repo.content'],
                        errors='replace') as f:
                        mydata[myfile] = f.read()
-       updated_items = update_dbentries(update_iter, mydata)
+       updated_items = update_dbentries(update_iter, mydata, eapi=eapi)
        for myfile, mycontent in updated_items.items():
                file_path = os.path.join(dbdir, myfile)
                write_atomic(file_path, mycontent, encoding=_encodings['repo.content'])
index 5893096d18b7017d7d36d2fa9c449406d6e3de95..27947532bf502e4ca30480f56e1ba3a3093a6a94 100644 (file)
@@ -345,6 +345,8 @@ class _pkg_str(_unicode):
                        # Avoid TypeError from _unicode.__init__ with PyPy.
                        cpv = _unicode_decode(cpv)
                _unicode.__init__(cpv)
+               if eapi is not None:
+                       self.__dict__['eapi'] = eapi
                self.__dict__['cpv_split'] = catpkgsplit(cpv, eapi=eapi)
                if self.cpv_split is None:
                        raise InvalidData(cpv)