From 8fc7b6a4a3c745a376ec3fcd63aa8ca796a0b29f Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Mon, 28 May 2007 09:31:26 +0000 Subject: Add new emaint targets called "moveinst" and "movebin" for applying package moves from $PORTDIR/profiles/updates/ on installed packages and binary packages. svn path=/main/trunk/; revision=6652 --- bin/emaint | 122 ++++++++++++++++++++++++++++++++++++++++++- pym/portage/__init__.py | 18 +++++-- pym/portage/dbapi/bintree.py | 17 +++--- pym/portage/dbapi/vartree.py | 13 +++-- 4 files changed, 153 insertions(+), 17 deletions(-) diff --git a/bin/emaint b/bin/emaint index 0152a08e1..d1efc0ab8 100755 --- a/bin/emaint +++ b/bin/emaint @@ -163,6 +163,124 @@ class BinhostHandler(object): locks.unlockfile(pkgindex_lock) return None +class MoveHandler(object): + + def __init__(self, tree): + self._tree = tree + self._portdir = tree.settings["PORTDIR"] + self._update_keys = ["DEPEND", "RDEPEND", "PDEPEND", "PROVIDE"] + + def _grab_global_updates(self, portdir): + from portage.update import grab_updates, parse_updates + updpath = os.path.join(portdir, "profiles", "updates") + try: + rawupdates = grab_updates(updpath) + except portage.exception.DirectoryNotFound: + rawupdates = [] + upd_commands = [] + errors = [] + for mykey, mystat, mycontent in rawupdates: + commands, errors = parse_updates(mycontent) + upd_commands.extend(commands) + errors.extend(errors) + return upd_commands, errors + + def check(self, onProgress=None): + updates, errors = self._grab_global_updates(self._portdir) + # Matching packages and moving them is relatively fast, so the + # progress bar is updated in indeterminate mode. + match = self._tree.dbapi.match + aux_get = self._tree.dbapi.aux_get + if onProgress: + onProgress(0, 0) + for i, update_cmd in enumerate(updates): + if update_cmd[0] == "move": + origcp, newcp = update_cmd[1:] + for cpv in match(origcp): + 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 = aux_get(cpv, ["SLOT"])[0] + if slot == origslot: + errors.append("'%s' slot moved from '%s' to '%s'" % \ + (cpv, origslot, newslot)) + if onProgress: + onProgress(0, 0) + + # Searching for updates in all the metadata is relatively slow, so this + # is where the progress bar comes out of indeterminate mode. + cpv_all = self._tree.dbapi.cpv_all() + cpv_all.sort() + maxval = len(cpv_all) + aux_update = self._tree.dbapi.aux_update + update_keys = self._update_keys + from itertools import izip + from portage.update import update_dbentries + if onProgress: + onProgress(maxval, 0) + for i, cpv in enumerate(cpv_all): + metadata = dict(izip(update_keys, aux_get(cpv, update_keys))) + metadata_updates = update_dbentries(updates, metadata) + if metadata_updates: + errors.append("'%s' has outdated metadata" % cpv) + if onProgress: + onProgress(maxval, i+1) + return errors + + def fix(self, onProgress=None): + updates, errors = self._grab_global_updates(self._portdir) + # Matching packages and moving them is relatively fast, so the + # progress bar is updated in indeterminate mode. + move = self._tree.dbapi.move_ent + slotmove = self._tree.dbapi.move_slot_ent + if onProgress: + onProgress(0, 0) + for i, update_cmd in enumerate(updates): + if update_cmd[0] == "move": + move(update_cmd) + elif update_cmd[0] == "slotmove": + slotmove(update_cmd) + if onProgress: + onProgress(0, 0) + + # Searching for updates in all the metadata is relatively slow, so this + # is where the progress bar comes out of indeterminate mode. + cpv_all = self._tree.dbapi.cpv_all() + cpv_all.sort() + maxval = len(cpv_all) + aux_get = self._tree.dbapi.aux_get + aux_update = self._tree.dbapi.aux_update + update_keys = self._update_keys + from itertools import izip + from portage.update import update_dbentries + if onProgress: + onProgress(maxval, 0) + for i, cpv in enumerate(cpv_all): + metadata = dict(izip(update_keys, aux_get(cpv, update_keys))) + metadata_updates = update_dbentries(updates, metadata) + if metadata_updates: + aux_update(cpv, metadata_updates) + if onProgress: + onProgress(maxval, i+1) + return errors + +class MoveInstalled(MoveHandler): + def name(): + return "moveinst" + name = staticmethod(name) + def __init__(self): + myroot = portage.settings["ROOT"] + MoveHandler.__init__(self, portage.db[myroot]["vartree"]) + +class MoveBinary(MoveHandler): + def name(): + return "movebin" + name = staticmethod(name) + def __init__(self): + myroot = portage.settings["ROOT"] + MoveHandler.__init__(self, portage.db[myroot]["bintree"]) + class VdbKeyHandler(object): def name(): return "vdbkeys" @@ -245,7 +363,9 @@ def emaint_main(myargv): # the need for hard coding. modules = { "world" : WorldHandler, - "binhost":BinhostHandler + "binhost":BinhostHandler, + "moveinst":MoveInstalled, + "movebin":MoveBinary } module_names = modules.keys() diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 0f90e2dd6..242bfb1b7 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -5058,13 +5058,23 @@ def global_updates(mysettings, trees, prev_mtimes): trees["/"]["bintree"] = binarytree("/", mysettings["PKGDIR"], settings=mysettings) + vardb = trees["/"]["vartree"].dbapi + bindb = trees["/"]["bintree"].dbapi for update_cmd in myupd: if update_cmd[0] == "move": - trees["/"]["vartree"].dbapi.move_ent(update_cmd) - trees["/"]["bintree"].move_ent(update_cmd) + moves = vardb.move_ent(update_cmd) + if moves: + writemsg_stdout(moves * "@") + moves = bindb.move_ent(update_cmd) + if moves: + writemsg_stdout(moves * "%") elif update_cmd[0] == "slotmove": - trees["/"]["vartree"].dbapi.move_slot_ent(update_cmd) - trees["/"]["bintree"].move_slot_ent(update_cmd) + moves = vardb.move_slot_ent(update_cmd) + if moves: + writemsg_stdout(moves * "s") + moves = bindb.move_slot_ent(update_cmd) + if moves: + writemsg_stdout(moves * "S") # The above global updates proceed quickly, so they # are considered a single mtimedb transaction. diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py index 8ef1ff23b..434480e48 100644 --- a/pym/portage/dbapi/bintree.py +++ b/pym/portage/dbapi/bintree.py @@ -15,6 +15,8 @@ import os, errno, stat class bindbapi(fakedbapi): def __init__(self, mybintree=None, settings=None): self.bintree = mybintree + self.move_ent = mybintree.move_ent + self.move_slot_ent = mybintree.move_slot_ent self.cpvdict={} self.cpdict={} if settings is None: @@ -130,8 +132,9 @@ class binarytree(object): origcat = origcp.split("/")[0] mynewcat = newcp.split("/")[0] origmatches=self.dbapi.cp_list(origcp) + moves = 0 if not origmatches: - return + return moves for mycpv in origmatches: mycpsplit = catpkgsplit(mycpv) @@ -153,8 +156,7 @@ class binarytree(object): noiselevel=-1) continue - #print ">>> Updating data in:",mycpv - writemsg_stdout("%") + moves += 1 mytbz2 = portage.xpak.tbz2(tbz2path) mydata = mytbz2.get_data() updated_items = update_dbentries([mylist], mydata) @@ -184,7 +186,7 @@ class binarytree(object): self._create_symlink(mynewcpv) self.dbapi.cpv_inject(mynewcpv) - return 1 + return moves def _remove_symlink(self, cpv): """Remove a ${PKGDIR}/${CATEGORY}/${PF}.tbz2 symlink and also remove @@ -235,8 +237,9 @@ class binarytree(object): raise InvalidAtom(pkg) origmatches = self.dbapi.match(pkg) + moves = 0 if not origmatches: - return + return moves for mycpv in origmatches: mycpsplit = catpkgsplit(mycpv) myoldpkg = mycpv.split("/")[1] @@ -257,10 +260,10 @@ class binarytree(object): if (slot[0] != origslot): continue - writemsg_stdout("S") + moves += 1 mydata["SLOT"] = newslot+"\n" mytbz2.recompose_mem(portage.xpak.xpak_mem(mydata)) - return 1 + return moves def update_ents(self, update_iter): if len(update_iter) == 0: diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index f0be27eba..906c3c97f 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -276,8 +276,9 @@ class vardbapi(dbapi): if not (isvalidatom(cp) and isjustname(cp)): raise InvalidPackageName(cp) origmatches = self.match(origcp, use_cache=0) + moves = 0 if not origmatches: - return + return moves for mycpv in origmatches: mycpsplit = catpkgsplit(mycpv) mynewcpv = newcp + "-" + mycpsplit[2] @@ -288,7 +289,7 @@ class vardbapi(dbapi): origpath = self.getpath(mycpv) if not os.path.exists(origpath): continue - writemsg_stdout("@") + moves += 1 if not os.path.exists(self.getpath(mynewcat)): #create the directory os.makedirs(self.getpath(mynewcat)) @@ -313,6 +314,7 @@ class vardbapi(dbapi): write_atomic(os.path.join(newpath, "CATEGORY"), mynewcat+"\n") fixdbentries([mylist], newpath) + return moves def update_ents(self, update_iter): """Run fixdbentries on all installed packages (time consuming). Like @@ -336,9 +338,9 @@ class vardbapi(dbapi): raise InvalidAtom(pkg) origmatches = self.match(pkg, use_cache=0) - + moves = 0 if not origmatches: - return + return moves for mycpv in origmatches: origpath = self.getpath(mycpv) if not os.path.exists(origpath): @@ -351,8 +353,9 @@ class vardbapi(dbapi): if (slot[0] != origslot): continue - writemsg_stdout("s") + moves += 1 write_atomic(os.path.join(origpath, "SLOT"), newslot+"\n") + return moves def cp_list(self, mycp, use_cache=1): mysplit=catsplit(mycp) -- cgit v1.2.3-1-g7c22