From: Zac Medico Date: Wed, 28 Jul 2010 04:30:45 +0000 (-0700) Subject: Tweak global updates handling so that updates from $PORTDIR are applied X-Git-Tag: v2.2_rc68~434 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3569643f9d0f5c7bf6723af3af0f5147a265fe68;p=portage.git 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 --- 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]