summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-07-27 21:30:45 -0700
committerZac Medico <zmedico@gentoo.org>2010-07-27 21:30:45 -0700
commit3569643f9d0f5c7bf6723af3af0f5147a265fe68 (patch)
tree4d6a7053a3ab16e8fbdd27abc8870a5ded00c6d3
parentd679b5db098641cbd9c4eeed6d4b5b888a6430f9 (diff)
downloadportage-3569643f9d0f5c7bf6723af3af0f5147a265fe68.tar.gz
portage-3569643f9d0f5c7bf6723af3af0f5147a265fe68.tar.bz2
portage-3569643f9d0f5c7bf6723af3af0f5147a265fe68.zip
Tweak global updates handling so that updates from $PORTDIR are applied
for all of the following cases: * package is missing repository metadata * package has repository metadata, but the source repository does not have a profiles/updates/ directory * package has repository metadata, but the source repository is not currently accessible via PORTDIR_OVERLAY
-rwxr-xr-xbin/emaint50
-rw-r--r--pym/_emerge/FakeVartree.py21
-rw-r--r--pym/portage/_global_updates.py33
-rw-r--r--pym/portage/dbapi/__init__.py21
-rw-r--r--pym/portage/dbapi/bintree.py5
-rw-r--r--pym/portage/dbapi/vartree.py5
6 files changed, 102 insertions, 33 deletions
diff --git a/bin/emaint b/bin/emaint
index 52990f7df..6a73c6fe2 100755
--- a/bin/emaint
+++ b/bin/emaint
@@ -230,6 +230,8 @@ class MoveHandler(object):
self._tree = tree
self._portdb = porttree.dbapi
self._update_keys = ["DEPEND", "RDEPEND", "PDEPEND", "PROVIDE"]
+ self._master_repo = \
+ self._portdb.getRepositoryName(self._portdb.porttree_root)
def _grab_global_updates(self):
from portage.update import grab_updates, parse_updates
@@ -240,8 +242,8 @@ class MoveHandler(object):
repo = self._portdb.getRepositoryPath(repo_name)
updpath = os.path.join(repo, "profiles", "updates")
if not os.path.isdir(updpath):
- # as a backwards-compatibility measure, fallback to PORTDIR
- updpath = os.path.join(self._portdb.porttree_root, "profiles", "updates")
+ continue
+
try:
rawupdates = grab_updates(updpath)
except portage.exception.DirectoryNotFound:
@@ -253,6 +255,9 @@ class MoveHandler(object):
errors.extend(errors)
retupdates[repo_name] = upd_commands
+ if self._master_repo in retupdates:
+ retupdates['DEFAULT'] = retupdates[self._master_repo]
+
return retupdates, errors
def check(self, onProgress=None):
@@ -264,17 +269,27 @@ class MoveHandler(object):
if onProgress:
onProgress(0, 0)
for repo, updates in allupdates.items():
+ if repo == 'DEFAULT':
+ continue
+ if not updates:
+ continue
+
+ def repo_match(repository):
+ return repository == repo or \
+ (repo == self._master_repo and \
+ repository not in allupdates)
+
for i, update_cmd in enumerate(updates):
if update_cmd[0] == "move":
origcp, newcp = update_cmd[1:]
for cpv in match(origcp):
- if aux_get(cpv, ["repository"])[0] == repo:
+ if repo_match(aux_get(cpv, ["repository"])[0]):
errors.append("'%s' moved to '%s'" % (cpv, newcp))
elif update_cmd[0] == "slotmove":
pkg, origslot, newslot = update_cmd[1:]
for cpv in match(pkg):
slot, prepo = aux_get(cpv, ["SLOT", "repository"])
- if slot == origslot and prepo == repo:
+ if slot == origslot and repo_match(prepo):
errors.append("'%s' slot moved from '%s' to '%s'" % \
(cpv, origslot, newslot))
if onProgress:
@@ -286,17 +301,22 @@ class MoveHandler(object):
cpv_all.sort()
maxval = len(cpv_all)
aux_update = self._tree.dbapi.aux_update
- update_keys = self._update_keys
+ meta_keys = self._update_keys + ['repository']
from portage.update import update_dbentries
if onProgress:
onProgress(maxval, 0)
for i, cpv in enumerate(cpv_all):
+ metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
+ repository = metadata.pop('repository')
try:
- updates = allupdates[aux_get(cpv, ['repository'])[0]]
+ updates = allupdates[repository]
except KeyError:
+ try:
+ updates = allupdates['DEFAULT']
+ except KeyError:
+ continue
+ if not updates:
continue
-
- metadata = dict(zip(update_keys, aux_get(cpv, update_keys)))
metadata_updates = update_dbentries(updates, metadata)
if metadata_updates:
errors.append("'%s' has outdated metadata" % cpv)
@@ -313,11 +333,21 @@ class MoveHandler(object):
if onProgress:
onProgress(0, 0)
for repo, updates in allupdates.items():
+ if repo == 'DEFAULT':
+ continue
+ if not updates:
+ continue
+
+ def repo_match(repository):
+ return repository == repo or \
+ (repo == self._master_repo and \
+ repository not in allupdates)
+
for i, update_cmd in enumerate(updates):
if update_cmd[0] == "move":
- move(update_cmd, repo_name=repo)
+ move(update_cmd, repo_match=repo_match)
elif update_cmd[0] == "slotmove":
- slotmove(update_cmd, repo_name=repo)
+ slotmove(update_cmd, repo_match=repo_match)
if onProgress:
onProgress(0, 0)
diff --git a/pym/_emerge/FakeVartree.py b/pym/_emerge/FakeVartree.py
index 22f9f3739..c74092d55 100644
--- a/pym/_emerge/FakeVartree.py
+++ b/pym/_emerge/FakeVartree.py
@@ -186,8 +186,8 @@ def grab_global_updates(portdb):
repo = portdb.getRepositoryPath(repo_name)
updpath = os.path.join(repo, "profiles", "updates")
if not os.path.isdir(updpath):
- # as a backwards-compatibility measure, fallback to PORTDIR
- updpath = os.path.join(portdb.porttree_root, "profiles", "updates")
+ continue
+
try:
rawupdates = grab_updates(updpath)
except portage.exception.DirectoryNotFound:
@@ -198,16 +198,27 @@ def grab_global_updates(portdb):
upd_commands.extend(commands)
retupdates[repo_name] = upd_commands
+ master_repo = portdb.getRepositoryName(portdb.porttree_root)
+ if master_repo in retupdates:
+ retupdates['DEFAULT'] = retupdates[master_repo]
+
return retupdates
def perform_global_updates(mycpv, mydb, myupdates):
+ aux_keys = ["DEPEND", "RDEPEND", "PDEPEND", 'repository']
+ aux_dict = dict(zip(aux_keys, mydb.aux_get(mycpv, aux_keys)))
+ repository = aux_dict.pop('repository')
try:
- mycommands = myupdates[mydb.aux_get(mycpv, ['repository'])[0]]
+ mycommands = myupdates[repository]
except KeyError:
+ try:
+ mycommands = myupdates['DEFAULT']
+ except KeyError:
+ return
+
+ if not mycommands:
return
- aux_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
- aux_dict = dict(zip(aux_keys, mydb.aux_get(mycpv, aux_keys)))
updates = update_dbentries(mycommands, aux_dict)
if updates:
mydb.aux_update(mycpv, updates)
diff --git a/pym/portage/_global_updates.py b/pym/portage/_global_updates.py
index cded5c45a..d3f55902d 100644
--- a/pym/portage/_global_updates.py
+++ b/pym/portage/_global_updates.py
@@ -55,6 +55,10 @@ def _global_updates(trees, prev_mtimes):
world_modified = False
world_warnings = set()
updpath_map = {}
+ # Maps repo_name to list of updates. If a given repo has no updates
+ # directory, it will be omitted. If a repo has an updates directory
+ # but none need to be applied (according to timestamp logic), the
+ # value in the dict will be an empty list.
repo_map = {}
timestamps = {}
@@ -62,8 +66,7 @@ def _global_updates(trees, prev_mtimes):
repo = portdb.getRepositoryPath(repo_name)
updpath = os.path.join(repo, "profiles", "updates")
if not os.path.isdir(updpath):
- # as a backwards-compatibility measure, fallback to PORTDIR
- updpath = os.path.join(portdb.porttree_root, "profiles", "updates")
+ continue
if updpath in updpath_map:
repo_map[repo_name] = updpath_map[updpath]
@@ -102,7 +105,20 @@ def _global_updates(trees, prev_mtimes):
writemsg("%s\n" % msg, noiselevel=-1)
retupd.extend(myupd)
+ master_repo = portdb.getRepositoryName(portdb.porttree_root)
+ if master_repo in repo_map:
+ repo_map['DEFAULT'] = repo_map[master_repo]
+
for repo_name, myupd in repo_map.items():
+ if repo_name == 'DEFAULT':
+ continue
+ if not myupd:
+ continue
+
+ def repo_match(repository):
+ return repository == repo_name or \
+ (repo_name == master_repo and repository not in repo_map)
+
def _world_repo_match(atoma, atomb):
"""
Check whether to perform a world change from atoma to atomb.
@@ -111,7 +127,8 @@ def _global_updates(trees, prev_mtimes):
can find a match for old atom name, warn about that.
"""
matches = vardb.match(atoma)
- if matches and vardb.aux_get(best(matches), ['repository'])[0] == repo_name:
+ if matches and \
+ repo_match(vardb.aux_get(best(matches), ['repository'])[0]):
if portdb.match(atoma):
world_warnings.add((atoma, atomb))
return True
@@ -132,19 +149,19 @@ def _global_updates(trees, prev_mtimes):
for update_cmd in myupd:
if update_cmd[0] == "move":
- moves = vardb.move_ent(update_cmd, repo_name=repo_name)
+ moves = vardb.move_ent(update_cmd, repo_match=repo_match)
if moves:
writemsg_stdout(moves * "@")
if bindb:
- moves = bindb.move_ent(update_cmd, repo_name=repo_name)
+ moves = bindb.move_ent(update_cmd, repo_match=repo_match)
if moves:
writemsg_stdout(moves * "%")
elif update_cmd[0] == "slotmove":
- moves = vardb.move_slot_ent(update_cmd, repo_name=repo_name)
+ moves = vardb.move_slot_ent(update_cmd, repo_match=repo_match)
if moves:
writemsg_stdout(moves * "s")
if bindb:
- moves = bindb.move_slot_ent(update_cmd, repo_name=repo_name)
+ moves = bindb.move_slot_ent(update_cmd, repo_match=repo_match)
if moves:
writemsg_stdout(moves * "S")
@@ -158,7 +175,7 @@ def _global_updates(trees, prev_mtimes):
for mykey, mtime in timestamps.items():
prev_mtimes[mykey] = mtime
- if repo_map:
+ if retupd:
do_upgrade_packagesmessage = False
# We gotta do the brute force updates for these now.
if mysettings.get("PORTAGE_CALLER") == "fixpackages" or \
diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
index b6b9175c6..4799b2582 100644
--- a/pym/portage/dbapi/__init__.py
+++ b/pym/portage/dbapi/__init__.py
@@ -229,9 +229,16 @@ class dbapi(object):
if repo_dict is None:
updates_list = updates
else:
- updates_list = repo_dict.get(repo)
- if updates_list is None:
- continue
+ try:
+ updates_list = repo_dict[repo]
+ except KeyError:
+ try:
+ updates_list = repo_dict['DEFAULT']
+ except KeyError:
+ continue
+
+ if not updates_list:
+ continue
metadata_updates = update_dbentries(updates_list, metadata)
if metadata_updates:
@@ -241,11 +248,12 @@ class dbapi(object):
if onProgress:
onProgress(maxval, i+1)
- def move_slot_ent(self, mylist, repo_name = None):
+ def move_slot_ent(self, mylist, repo_match=None):
"""This function takes a sequence:
Args:
mylist: a sequence of (package, originalslot, newslot)
- repo_name: repository from which update is originated
+ 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
"""
@@ -260,7 +268,8 @@ class dbapi(object):
slot = self.aux_get(mycpv, ["SLOT"])[0]
if slot != origslot:
continue
- if repo_name and self.aux_get(mycpv, ['repository'])[0] != repo_name:
+ if repo_match is not None \
+ and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
continue
moves += 1
mydata = {"SLOT": newslot+"\n"}
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index 84c51a977..f3f7aff98 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -288,7 +288,7 @@ class binarytree(object):
remotepkgs = property(_get_remotepkgs, _set_remotepkgs, _del_remotepkgs,
"Deprecated self.remotepkgs, only for backward compatibility")
- def move_ent(self, mylist, repo_name = None):
+ def move_ent(self, mylist, repo_match=None):
if not self.populated:
self.populate()
origcp = mylist[1]
@@ -307,7 +307,8 @@ class binarytree(object):
if mycpv_cp != origcp:
# Ignore PROVIDE virtual match.
continue
- if repo_name and self.aux_get(mycpv, ['repository'])[0] != repo_name:
+ if repo_match is not None \
+ and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
continue
mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
myoldpkg = catsplit(mycpv)[1]
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 6dbb51379..dbdb7d0b5 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -923,7 +923,7 @@ class vardbapi(dbapi):
return True
return False
- def move_ent(self, mylist, repo_name = None):
+ def move_ent(self, mylist, repo_match=None):
origcp = mylist[1]
newcp = mylist[2]
@@ -940,7 +940,8 @@ class vardbapi(dbapi):
if mycpv_cp != origcp:
# Ignore PROVIDE virtual match.
continue
- if repo_name and self.aux_get(mycpv, ['repository'])[0] != repo_name:
+ if repo_match is not None \
+ and not repo_match(self.aux_get(mycpv, ['repository'])[0]):
continue
mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
mynewcat = catsplit(newcp)[0]