diff options
author | Zac Medico <zmedico@gentoo.org> | 2012-09-19 12:48:24 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-09-19 12:48:24 -0700 |
commit | 60d7d3cf4364a1cc41cf98b57359a0faf1fdc5bd (patch) | |
tree | e464bd59dc904f3a16edb998b9838d3fa01b922f | |
parent | Atom: don't allow :slot* syntax (diff) | |
download | portage-60d7d3cf4364a1cc41cf98b57359a0faf1fdc5bd.tar.gz portage-60d7d3cf4364a1cc41cf98b57359a0faf1fdc5bd.tar.bz2 portage-60d7d3cf4364a1cc41cf98b57359a0faf1fdc5bd.zip |
update_dbentry: improve slotmove support
This could be especially useful for "built" slot operator deps, in
order to avoid having a slotmove trigger unnecessary rebuilds.
-rw-r--r-- | pym/portage/tests/update/test_update_dbentry.py | 26 | ||||
-rw-r--r-- | pym/portage/update.py | 46 |
2 files changed, 65 insertions, 7 deletions
diff --git a/pym/portage/tests/update/test_update_dbentry.py b/pym/portage/tests/update/test_update_dbentry.py index e13cfed74..ac16a8ae3 100644 --- a/pym/portage/tests/update/test_update_dbentry.py +++ b/pym/portage/tests/update/test_update_dbentry.py @@ -6,14 +6,40 @@ import textwrap import portage from portage import os +from portage.dep import Atom from portage.tests import TestCase from portage.tests.resolver.ResolverPlayground import ResolverPlayground +from portage.update import update_dbentry from portage.util import ensure_dirs from portage._global_updates import _do_global_updates class UpdateDbentryTestCase(TestCase): def testUpdateDbentryTestCase(self): + cases = ( + (("slotmove", Atom("dev-libs/A"), "0", "1"), "1", + " dev-libs/A:0 ", " dev-libs/A:1 "), + + (("slotmove", Atom("dev-libs/A"), "0", "1"), "1", + " >=dev-libs/A-1:0 ", " >=dev-libs/A-1:1 "), + + (("slotmove", Atom("dev-libs/A"), "0", "1"), "5_pre2", + " dev-libs/A:0/1=[foo] ", " dev-libs/A:1/1=[foo] "), + + (("slotmove", Atom("dev-libs/A"), "0", "1"), "5_pre2", + " dev-libs/A:0/1[foo] ", " dev-libs/A:1/1[foo] "), + + (("slotmove", Atom("dev-libs/A"), "0", "1"), "5_pre2", + " dev-libs/A:0/0[foo] ", " dev-libs/A:1/1[foo] "), + + (("slotmove", Atom("dev-libs/A"), "0", "1"), "5_pre2", + " dev-libs/A:0=[foo] ", " dev-libs/A:1=[foo] "), + ) + for update_cmd, eapi, input_str, output_str in cases: + result = update_dbentry(update_cmd, input_str, eapi=eapi) + self.assertEqual(result, output_str) + + def testUpdateDbentryDbapiTestCase(self): ebuilds = { diff --git a/pym/portage/update.py b/pym/portage/update.py index 121e95720..017f71f62 100644 --- a/pym/portage/update.py +++ b/pym/portage/update.py @@ -22,7 +22,7 @@ portage.proxy.lazyimport.lazyimport(globals(), ) from portage.const import USER_CONFIG_PATH -from portage.dep import _get_slot_re +from portage.dep import Atom, _get_slot_re from portage.eapi import _get_eapi_attrs from portage.exception import DirectoryNotFound, InvalidAtom, PortageException from portage.localization import _ @@ -57,12 +57,44 @@ def update_dbentry(update_cmd, mycontent, eapi=None): return "".join(matchobj.groups()) mycontent = re.sub("(%s-)(\\S*)" % old_value, myreplace, mycontent) elif update_cmd[0] == "slotmove" and update_cmd[1].operator is None: - pkg, origslot, newslot = update_cmd[1:] - old_value = "%s:%s" % (pkg, origslot) - if old_value in mycontent: - old_value = re.escape(old_value) - new_value = "%s:%s" % (pkg, newslot) - mycontent = re.sub(old_value+"($|\\s)", new_value+"\\1", mycontent) + orig_atom, origslot, newslot = update_cmd[1:] + orig_cp = orig_atom.cp + + # We don't support versioned slotmove atoms here, since it can be + # difficult to determine if the version constraints really match + # the atoms that we're trying to update. + if orig_atom.version is None and orig_cp in mycontent: + # this split preserves existing whitespace + split_content = re.split(r'(\s+)', mycontent) + modified = False + for i, token in enumerate(split_content): + if orig_cp not in token: + continue + try: + atom = Atom(token, eapi=eapi) + except InvalidAtom: + continue + if atom.cp != orig_cp: + continue + if atom.slot is None or atom.slot != origslot: + continue + + slot_part = newslot + if atom.sub_slot is not None: + if atom.sub_slot == origslot: + sub_slot = newslot + else: + sub_slot = atom.sub_slot + slot_part += "/" + sub_slot + if atom.slot_operator is not None: + slot_part += atom.slot_operator + + split_content[i] = atom.with_slot(slot_part) + modified = True + + if modified: + mycontent = "".join(split_content) + return mycontent def update_dbentries(update_iter, mydata, eapi=None): |