Add new emaint targets called "moveinst" and "movebin" for applying package moves...
authorZac Medico <zmedico@gentoo.org>
Mon, 28 May 2007 09:31:26 +0000 (09:31 -0000)
committerZac Medico <zmedico@gentoo.org>
Mon, 28 May 2007 09:31:26 +0000 (09:31 -0000)
svn path=/main/trunk/; revision=6652

bin/emaint
pym/portage/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/vartree.py

index 0152a08e137749c691b1bf1eab37f4884d235a66..d1efc0ab8fd695a012a5ac75c7f1c4414bbced78 100755 (executable)
@@ -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()
index 0f90e2dd6a833e39a04146bd32b652dbbaf0eb67..242bfb1b78abf74bf7d577b68625b7128d546db8 100644 (file)
@@ -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.
index 8ef1ff23b929a0509630295c02992c70f63e53c5..434480e48ff7e383a7855123f4840d4cd848e07f 100644 (file)
@@ -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:
index f0be27ebafd3424f9266cacc81c58cbbd948c83c..906c3c97f3908d1549ca875d6b6f1f5f792590d1 100644 (file)
@@ -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)