From 9ea1eb84c6c2cd91e31196471ec8ad4339988611 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Tue, 17 Jul 2012 15:21:04 -0700 Subject: [PATCH] Propagate EAPI for update_dbentry (bug #426476). --- bin/emaint | 7 +- pym/_emerge/FakeVartree.py | 5 +- pym/portage/dbapi/__init__.py | 7 +- pym/portage/dbapi/bintree.py | 6 +- pym/portage/dbapi/vartree.py | 6 +- pym/portage/tests/update/test_move_ent.py | 109 ++++++++++++++++++++++ pym/portage/update.py | 8 +- pym/portage/versions.py | 2 + 8 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 pym/portage/tests/update/test_move_ent.py diff --git a/bin/emaint b/bin/emaint index 5f54f6af5..21604511b 100755 --- a/bin/emaint +++ b/bin/emaint @@ -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: diff --git a/pym/_emerge/FakeVartree.py b/pym/_emerge/FakeVartree.py index e62058540..ce15f5a36 100644 --- a/pym/_emerge/FakeVartree.py +++ b/pym/_emerge/FakeVartree.py @@ -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) diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py index ac8d31169..b999fb5df 100644 --- a/pym/portage/dbapi/__init__.py +++ b/pym/portage/dbapi/__init__.py @@ -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: diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index 1048cc108..e3de50f08 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -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", diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index dddc094d2..264790a03 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -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 index 000000000..716a89d77 --- /dev/null +++ b/pym/portage/tests/update/test_move_ent.py @@ -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() diff --git a/pym/portage/update.py b/pym/portage/update.py index a5cb92eda..a66c60b9a 100644 --- a/pym/portage/update.py +++ b/pym/portage/update.py @@ -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']) diff --git a/pym/portage/versions.py b/pym/portage/versions.py index 5893096d1..27947532b 100644 --- a/pym/portage/versions.py +++ b/pym/portage/versions.py @@ -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) -- 2.26.2