aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-07-13 16:33:49 -0700
committerZac Medico <zmedico@gentoo.org>2012-07-13 16:33:49 -0700
commitdde6df65ecbc522dc23cb8d24be3e4dd52657da8 (patch)
tree9b0ca15a0ed3aa826654a6eb8c090e510c175268
parentvardbapi: use float mtime for aux cache (diff)
downloadportage-dde6df65ecbc522dc23cb8d24be3e4dd52657da8.tar.gz
portage-dde6df65ecbc522dc23cb8d24be3e4dd52657da8.tar.bz2
portage-dde6df65ecbc522dc23cb8d24be3e4dd52657da8.zip
slotmove: fix handling for EAPI 4-slot-abiv2.2.0_alpha118
This is just a really minimal fix, in order to prevent slotmove from behaving incorrectly with packages that use EAPI 4-slot-abi. Any slotmove commands that try so specify a sub-slot are treated as invalid for now, since that will required additional EAPI conditional logic, as reported in bug #426476.
-rw-r--r--pym/portage/_global_updates.py14
-rw-r--r--pym/portage/dbapi/__init__.py28
-rw-r--r--pym/portage/tests/emerge/test_global_updates.py6
-rw-r--r--pym/portage/tests/update/__init__.py2
-rw-r--r--pym/portage/tests/update/__test__0
-rw-r--r--pym/portage/tests/update/test_move_slot_ent.py149
-rw-r--r--pym/portage/update.py23
7 files changed, 206 insertions, 16 deletions
diff --git a/pym/portage/_global_updates.py b/pym/portage/_global_updates.py
index 51750431d..c0f3df0b6 100644
--- a/pym/portage/_global_updates.py
+++ b/pym/portage/_global_updates.py
@@ -1,4 +1,4 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -32,11 +32,15 @@ def _global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
"""
# only do this if we're root and not running repoman/ebuild digest
- retupd = False
if secpass < 2 or \
"SANDBOX_ACTIVE" in os.environ or \
len(trees) != 1:
- return retupd
+ return False
+
+ return _do_global_updates(trees, prev_mtimes,
+ quiet=quiet, if_mtime_changed=if_mtime_changed)
+
+def _do_global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
root = trees._running_eroot
mysettings = trees[root]["vartree"].settings
portdb = trees[root]["porttree"].dbapi
@@ -61,6 +65,7 @@ def _global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
repo_map = {}
timestamps = {}
+ retupd = False
update_notice_printed = False
for repo_name in portdb.getRepositories():
repo = portdb.getRepositoryPath(repo_name)
@@ -237,8 +242,7 @@ def _global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
# Update progress above is indicated by characters written to stdout so
# we print a couple new lines here to separate the progress output from
# what follows.
- print()
- print()
+ writemsg_stdout("\n\n")
if do_upgrade_packagesmessage and bindb and \
bindb.cpv_all():
diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
index 34b1d4705..ac8d31169 100644
--- a/pym/portage/dbapi/__init__.py
+++ b/pym/portage/dbapi/__init__.py
@@ -8,7 +8,7 @@ import re
import portage
portage.proxy.lazyimport.lazyimport(globals(),
'portage.dbapi.dep_expand:dep_expand@_dep_expand',
- 'portage.dep:match_from_list,_match_slot',
+ 'portage.dep:Atom,match_from_list,_match_slot',
'portage.output:colorize',
'portage.util:cmp_sort_key,writemsg',
'portage.versions:catsplit,catpkgsplit,vercmp,_pkg_str',
@@ -312,27 +312,39 @@ class dbapi(object):
def move_slot_ent(self, mylist, repo_match=None):
"""This function takes a sequence:
Args:
- mylist: a sequence of (package, originalslot, newslot)
+ mylist: a sequence of (atom, originalslot, newslot)
repo_match: callable that takes single repo_name argument
and returns True if the update should be applied
Returns:
The number of slotmoves this function did
"""
- pkg = mylist[1]
+ atom = mylist[1]
origslot = mylist[2]
newslot = mylist[3]
- origmatches = self.match(pkg)
+
+ try:
+ atom.with_slot
+ except AttributeError:
+ atom = Atom(atom).with_slot(origslot)
+ else:
+ atom = atom.with_slot(origslot)
+
+ origmatches = self.match(atom)
moves = 0
if not origmatches:
return moves
for mycpv in origmatches:
- slot = self.aux_get(mycpv, ["SLOT"])[0]
- if slot != origslot:
+ try:
+ mycpv = self._pkg_str(mycpv, atom.repo)
+ except (KeyError, InvalidData):
continue
- if repo_match is not None \
- and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
+ if repo_match is not None and not repo_match(mycpv.repo):
continue
moves += 1
+ if "/" not in newslot and \
+ mycpv.slot_abi and \
+ mycpv.slot_abi not in (mycpv.slot, newslot):
+ newslot = "%s/%s" % (newslot, mycpv.slot_abi)
mydata = {"SLOT": newslot+"\n"}
self.aux_update(mycpv, mydata)
return moves
diff --git a/pym/portage/tests/emerge/test_global_updates.py b/pym/portage/tests/emerge/test_global_updates.py
index 735562100..eb5431059 100644
--- a/pym/portage/tests/emerge/test_global_updates.py
+++ b/pym/portage/tests/emerge/test_global_updates.py
@@ -1,4 +1,4 @@
-# Copyright 2011 Gentoo Foundation
+# Copyright 2011-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.tests import TestCase
@@ -15,6 +15,8 @@ slotmove invalid_atom 0 3
slotmove !=invalid/blocker-3* 0 3
slotmove =valid/atom-3* 0 3 invalid_extra_token
slotmove =valid/atom-3* 0 3
+slotmove =valid/atom-3* 0 3/3.1
+slotmove =valid/atom-3* 0/0 3
move valid/atom1 valid/atom2 invalid_extra_token
move valid/atom1 invalid_atom2
move invalid_atom1 valid/atom2
@@ -28,7 +30,7 @@ move valid/atom1 valid/atom2
['slotmove', Atom('=valid/atom-3*'), '0', '3'],
['move', Atom('valid/atom1'), Atom('valid/atom2')],
],
- 10,
+ 12,
),
)
diff --git a/pym/portage/tests/update/__init__.py b/pym/portage/tests/update/__init__.py
new file mode 100644
index 000000000..418ad862b
--- /dev/null
+++ b/pym/portage/tests/update/__init__.py
@@ -0,0 +1,2 @@
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/portage/tests/update/__test__ b/pym/portage/tests/update/__test__
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/pym/portage/tests/update/__test__
diff --git a/pym/portage/tests/update/test_move_slot_ent.py b/pym/portage/tests/update/test_move_slot_ent.py
new file mode 100644
index 000000000..64475bcd5
--- /dev/null
+++ b/pym/portage/tests/update/test_move_slot_ent.py
@@ -0,0 +1,149 @@
+# 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 MoveSlotEntTestCase(TestCase):
+
+ def testMoveSlotEnt(self):
+
+ ebuilds = {
+
+ "dev-libs/A-2::dont_apply_updates" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.30",
+ },
+
+ "dev-libs/B-2::dont_apply_updates" : {
+ "SLOT": "0",
+ },
+
+ "dev-libs/C-2.1::dont_apply_updates" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.1",
+ },
+
+ }
+
+ installed = {
+
+ "dev-libs/A-1::test_repo" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.30",
+ },
+
+ "dev-libs/B-1::test_repo" : {
+ "SLOT": "0",
+ },
+
+ "dev-libs/C-1::test_repo" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/1",
+ },
+
+ }
+
+ binpkgs = {
+
+ "dev-libs/A-1::test_repo" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.30",
+ },
+
+ "dev-libs/A-2::dont_apply_updates" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.30",
+ },
+
+ "dev-libs/B-1::test_repo" : {
+ "SLOT": "0",
+ },
+
+ "dev-libs/B-2::dont_apply_updates" : {
+ "SLOT": "0",
+ },
+
+ "dev-libs/C-1::test_repo" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/1",
+ },
+
+ "dev-libs/C-2.1::dont_apply_updates" : {
+ "EAPI": "4-slot-abi",
+ "SLOT": "0/2.1",
+ },
+
+ }
+
+ updates = textwrap.dedent("""
+ slotmove dev-libs/A 0 2
+ slotmove dev-libs/B 0 1
+ slotmove dev-libs/C 0 1
+ """)
+
+ 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
+
+ # 0/2.30 -> 2/2.30
+ self.assertEqual("2/2.30",
+ vardb.aux_get("dev-libs/A-1", ["SLOT"])[0])
+ self.assertEqual("2/2.30",
+ bindb.aux_get("dev-libs/A-1", ["SLOT"])[0])
+
+ # 0 -> 1
+ self.assertEqual("1",
+ vardb.aux_get("dev-libs/B-1", ["SLOT"])[0])
+ self.assertEqual("1",
+ bindb.aux_get("dev-libs/B-1", ["SLOT"])[0])
+
+ # 0/1 -> 1 (equivalent to 1/1)
+ self.assertEqual("1",
+ vardb.aux_get("dev-libs/C-1", ["SLOT"])[0])
+ self.assertEqual("1",
+ bindb.aux_get("dev-libs/C-1", ["SLOT"])[0])
+
+ # dont_apply_updates
+ self.assertEqual("0/2.30",
+ bindb.aux_get("dev-libs/A-2", ["SLOT"])[0])
+ self.assertEqual("0",
+ bindb.aux_get("dev-libs/B-2", ["SLOT"])[0])
+ self.assertEqual("0/2.1",
+ bindb.aux_get("dev-libs/C-2.1", ["SLOT"])[0])
+
+ finally:
+ playground.cleanup()
diff --git a/pym/portage/update.py b/pym/portage/update.py
index 34e466366..a5cb92eda 100644
--- a/pym/portage/update.py
+++ b/pym/portage/update.py
@@ -22,6 +22,8 @@ portage.proxy.lazyimport.lazyimport(globals(),
)
from portage.const import USER_CONFIG_PATH
+from portage.dep import _get_slot_re
+from portage.eapi import _get_eapi_attrs
from portage.exception import DirectoryNotFound, InvalidAtom, PortageException
from portage.localization import _
@@ -30,7 +32,7 @@ if sys.hexversion >= 0x3000000:
ignored_dbentries = ("CONTENTS", "environment.bz2")
-def update_dbentry(update_cmd, mycontent):
+def update_dbentry(update_cmd, mycontent, eapi=None):
if update_cmd[0] == "move":
old_value = str(update_cmd[1])
if old_value in mycontent:
@@ -143,6 +145,8 @@ def grab_updates(updpath, prev_mtimes=None):
def parse_updates(mycontent):
"""Valid updates are returned as a list of split update commands."""
+ eapi_attrs = _get_eapi_attrs(None)
+ slot_re = _get_slot_re(eapi_attrs)
myupd = []
errors = []
mylines = mycontent.splitlines()
@@ -194,6 +198,23 @@ def parse_updates(mycontent):
errors.append(_("ERROR: Malformed update entry '%s'") % myline)
continue
+ invalid_slot = False
+ for slot in (origslot, newslot):
+ m = slot_re.match(slot)
+ if m is None:
+ invalid_slot = True
+ break
+ if "/" in slot:
+ # Don't support EAPI 4-slot-abi style SLOT in slotmove
+ # yet, since the relevant code isn't aware of EAPI yet
+ # (see bug #426476).
+ invalid_slot = True
+ break
+
+ if invalid_slot:
+ errors.append(_("ERROR: Malformed update entry '%s'") % myline)
+ continue
+
# The list of valid updates is filtered by continue statements above.
myupd.append(mysplit)
return myupd, errors