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"
# the need for hard coding.
modules = {
"world" : WorldHandler,
- "binhost":BinhostHandler
+ "binhost":BinhostHandler,
+ "moveinst":MoveInstalled,
+ "movebin":MoveBinary
}
module_names = modules.keys()
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.
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:
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)
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)
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
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]
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:
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]
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))
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
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):
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)