Merged from trunk 6646:6673
authorFabian Groffen <grobian@gentoo.org>
Wed, 30 May 2007 17:56:11 +0000 (17:56 -0000)
committerFabian Groffen <grobian@gentoo.org>
Wed, 30 May 2007 17:56:11 +0000 (17:56 -0000)
   +------------------------------------------------------------------------+
   | 6647    | Fix typo.                                                    |
   | zmedico |                                                              |
   |---------+--------------------------------------------------------------|
   | 6648    | For bug #180079, fix a KeyError so that a search for the     |
   | zmedico | empty string will go ahead and match all packages.           |
   |---------+--------------------------------------------------------------|
   | 6650    | For bug #180009, add a PORTAGE_RSYNC_INITIAL_TIMEOUT config  |
   | zmedico | variable. The default is 15 seconds and it can be disabled   |
   |         | by setting it to 0.                                          |
   |---------+--------------------------------------------------------------|
   | 6652    | Add new emaint targets called "moveinst" and "movebin" for   |
   | zmedico | applying package moves from $PORTDIR/profiles/updates/ on    |
   |         | installed packages and binary packages.                      |
   |---------+--------------------------------------------------------------|
   | 6653    | Fix emaint world $ROOT handling.                             |
   | zmedico |                                                              |
   |---------+--------------------------------------------------------------|
   | 6654    | Cap the progress bar columns at 80 since it looks ridiculous |
   | zmedico | when it gets too wide.                                       |
   |---------+--------------------------------------------------------------|
   | 6655    | Include IUSE in the Package index so that it can be used for |
   | zmedico | --newuse calculations.                                       |
   |---------+--------------------------------------------------------------|
   | 6656    | Fix binarytree.gettbz2() so that it works without            |
   | zmedico | $PKGDIR/All/ and inserts the downloaded package into the     |
   |         | local index.                                                 |
   |---------+--------------------------------------------------------------|
   | 6657    | For bug #179870, add support for cpv:slot in                 |
   | zmedico | match_from_list() and use it to make config.setcpv()         |
   |         | distinguish slot atoms in package.use.                       |
   |---------+--------------------------------------------------------------|
   | 6659    | Don't pass slotted packages into pkgsplit since it doesn't   |
   | zmedico | handle them.                                                 |
   |---------+--------------------------------------------------------------|
   | 6661    | Fix dep_getcpv() so that it always properly removes the slot |
   | zmedico | regardless of which operator is present.                     |
   |---------+--------------------------------------------------------------|
   | 6663    | Fix get_operator() and best_match_to_list() so that slot     |
   | zmedico | deps mesh properly with operators.                           |
   |---------+--------------------------------------------------------------|
   | 6665    | For bug #179870, correctly handle slot deps in the profile's |
   | zmedico | package.* files.                                             |
   |---------+--------------------------------------------------------------|
   | 6667    | For bug #180222, make ecompressdir use -f for the automatic  |
   | zmedico | decompression phase.                                         |
   |---------+--------------------------------------------------------------|
   | 6669    | Fix slot handling at the beginning of match_from_list().     |
   | zmedico |                                                              |
   |---------+--------------------------------------------------------------|
   | 6671    | For bug #61732, support -flag in USE (instead of just        |
   | zmedico | +flag). Given the current default USE_ORDER, -flag in IUSE   |
   |         | has no effect.                                               |
   |---------+--------------------------------------------------------------|
   | 6673    | Return a copy of the cached result from match_from_list().   |
   | zmedico |                                                              |
   +------------------------------------------------------------------------+

svn path=/main/branches/prefix/; revision=6675

bin/ebuild.sh
bin/ecompressdir
bin/emaint
man/make.conf.5
pym/emerge/__init__.py
pym/portage/__init__.py
pym/portage/dbapi/bintree.py
pym/portage/dbapi/vartree.py
pym/portage/dep.py
pym/portage/output.py

index 86dcf0ef2b8c83cc8980088ab2cd0299366110c1..af075880f1b39b0258be49b43d1bda9cd9c27bfb 100755 (executable)
@@ -1517,7 +1517,7 @@ if [ "${EBUILD_PHASE}" != "depend" ]; then
        # Make IUSE defaults backward compatible with all the old shell code.
        iuse_temp=""
        for x in ${IUSE} ; do
-               if [[ ${x} == +* ]]; then
+               if [[ ${x} == +* ]] || [[ ${x} == -* ]] ; then
                        iuse_temp="${iuse_temp} ${x:1}"
                else
                        iuse_temp="${iuse_temp} ${x}"
index 4b685f9daae8818e66fe81270e060439541feccf..b99de97150573b5c8f1345ec18d849c6604a34b2 100755 (executable)
@@ -115,9 +115,9 @@ for dir in "$@" ; do
        find "${dir}" -type f -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
 
        # not uncommon for packages to compress doc files themselves
-       funk_up_dir "decompress" ".Z" "gunzip"
-       funk_up_dir "decompress" ".gz" "gunzip"
-       funk_up_dir "decompress" ".bz2" "bunzip2"
+       funk_up_dir "decompress" ".Z" "gunzip -f"
+       funk_up_dir "decompress" ".gz" "gunzip -f"
+       funk_up_dir "decompress" ".bz2" "bunzip2 -f"
 
        # forcibly break all hard links as some compressors whine about it
        find "${dir}" -type f -links +1 -exec env file="{}" sh -c \
index 17e6ef15a660ef451612b301f53b85462179b69d..70ccb775bb9ac56db6d04e6051f9299c8038d3ab 100755 (executable)
@@ -24,12 +24,12 @@ class WorldHandler(object):
                self.not_installed = []
                self.invalid_category = []
                self.okay = []
-               self.world_file = os.path.join("/", portage.const.WORLD_FILE)
-               self.found = os.access(self.world_file, os.R_OK)
 
        def _check_world(self, onProgress):
                categories = set(portage.settings.categories)
                myroot = portage.settings["ROOT"]
+               self.world_file = os.path.join(myroot, portage.const.WORLD_FILE)
+               self.found = os.access(self.world_file, os.R_OK)
                vardb = portage.db[myroot]["vartree"].dbapi
 
                world_atoms = open(self.world_file).read().split()
@@ -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 fef0c6c9c9f096363859794d11405c7238faee8f..492121d85f1b66e9914401df3b0e41f59d5ad342 100644 (file)
@@ -356,6 +356,12 @@ emerge is running at.  In other words, this will not set the nice level,
 it will increment it.  For more information about nice levels and what
 are acceptable ranges, see \fBnice\fR(1).
 .TP
+\fBPORTAGE_RSYNC_INITIAL_TIMEOUT\fR = \fIinteger\fR
+Used by \fBemerge \-\-sync\fR as a timeout for the initial connection to an
+rsync server.
+.br
+Defaults to 15 seconds.
+.TP
 \fBPORTAGE_RSYNC_EXTRA_OPTS\fR = \fI[rsync options string]\fR
 Additional rsync options to be used by \fBemerge \-\-sync\fR.
 .br
index 8466135b15867ca46ef0d354fad2cef923cb6873..f64d1dd074f872f7b6a4cfc33911293d81dd2639 100644 (file)
@@ -399,10 +399,10 @@ class search:
                print "Searching...   ",
 
                regexsearch = False
-               if self.searchkey[0] == '%':
+               if self.searchkey.startswith('%'):
                        regexsearch = True
                        self.searchkey = self.searchkey[1:]
-               if self.searchkey[0] == '@':
+               if self.searchkey.startswith('@'):
                        match_category = 1
                        self.searchkey = self.searchkey[1:]
                if regexsearch:
@@ -599,7 +599,7 @@ def genericdict(mylist):
 
 def filter_iuse_defaults(iuse):
        for flag in iuse:
-               if flag.startswith("+"):
+               if flag.startswith("+") or flag.startswith("-"):
                        yield flag[1:]
                else:
                        yield flag
@@ -4059,6 +4059,12 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                pass
                del content
 
+               try:
+                       rsync_initial_timeout = \
+                               int(settings.get("PORTAGE_RSYNC_INITIAL_TIMEOUT", "15"))
+               except ValueError:
+                       rsync_initial_timeout = 15
+
                try:
                        if settings.has_key("RSYNC_RETRIES"):
                                print yellow("WARNING:")+" usage of RSYNC_RETRIES is deprecated, use PORTAGE_RSYNC_RETRIES instead"
@@ -4168,14 +4174,16 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                        # Timeout here in case the server is unresponsive.  The
                                        # --timeout rsync option doesn't apply to the initial
                                        # connection attempt.
-                                       signal.alarm(15)
+                                       if rsync_initial_timeout:
+                                               signal.alarm(rsync_initial_timeout)
                                        try:
                                                mypids.extend(portage.process.spawn(
                                                        mycommand, env=settings.environ(), returnpid=True))
                                                exitcode = os.waitpid(mypids[0], 0)[1]
                                                content = portage.grabfile(tmpservertimestampfile)
                                        finally:
-                                               signal.alarm(0)
+                                               if rsync_initial_timeout:
+                                                       signal.alarm(0)
                                                try:
                                                        os.unlink(tmpservertimestampfile)
                                                except OSError:
index c4124830243a9f762e43ad96ee3aa753b35eb39c..7f2108cc65b73581f5c6e225cc4b2aa6e13b7be1 100644 (file)
@@ -1699,11 +1699,18 @@ class config:
                has_changed = False
                self.mycpv = mycpv
                cp = dep_getkey(mycpv)
+               cpv_slot = self.mycpv
                pkginternaluse = ""
                if mydb:
-                       pkginternaluse = " ".join([x[1:] \
-                               for x in mydb.aux_get(mycpv, ["IUSE"])[0].split() \
-                               if x.startswith("+")])
+                       slot, iuse = mydb.aux_get(self.mycpv, ["SLOT", "IUSE"])
+                       cpv_slot = "%s:%s" % (self.mycpv, slot)
+                       pkginternaluse = []
+                       for x in iuse.split():
+                               if x.startswith("+"):
+                                       pkginternaluse.append(x[1:])
+                               elif x.startswith("-"):
+                                       pkginternaluse.append(x)
+                       pkginternaluse = " ".join(pkginternaluse)
                if pkginternaluse != self.configdict["pkginternal"].get("USE", ""):
                        self.configdict["pkginternal"]["USE"] = pkginternaluse
                        has_changed = True
@@ -1712,7 +1719,7 @@ class config:
                        defaults.append(self.make_defaults_use[i])
                        cpdict = self.pkgprofileuse[i].get(cp, None)
                        if cpdict:
-                               best_match = best_match_to_list(self.mycpv, cpdict.keys())
+                               best_match = best_match_to_list(cpv_slot, cpdict.keys())
                                if best_match:
                                        defaults.append(cpdict[best_match])
                defaults = " ".join(defaults)
@@ -1724,7 +1731,7 @@ class config:
                        useforce.append(self.useforce_list[i])
                        cpdict = self.puseforce_list[i].get(cp, None)
                        if cpdict:
-                               best_match = best_match_to_list(self.mycpv, cpdict.keys())
+                               best_match = best_match_to_list(cpv_slot, cpdict.keys())
                                if best_match:
                                        useforce.append(cpdict[best_match])
                useforce = set(stack_lists(useforce, incremental=True))
@@ -1736,7 +1743,7 @@ class config:
                        usemask.append(self.usemask_list[i])
                        cpdict = self.pusemask_list[i].get(cp, None)
                        if cpdict:
-                               best_match = best_match_to_list(self.mycpv, cpdict.keys())
+                               best_match = best_match_to_list(cpv_slot, cpdict.keys())
                                if best_match:
                                        usemask.append(cpdict[best_match])
                usemask = set(stack_lists(usemask, incremental=True))
@@ -1745,10 +1752,11 @@ class config:
                        has_changed = True
                oldpuse = self.puse
                self.puse = ""
-               if self.pusedict.has_key(cp):
-                       self.pusekey = best_match_to_list(self.mycpv, self.pusedict[cp].keys())
+               cpdict = self.pusedict.get(cp)
+               if cpdict:
+                       self.pusekey = best_match_to_list(cpv_slot, cpdict.keys())
                        if self.pusekey:
-                               self.puse = " ".join(self.pusedict[cp][self.pusekey])
+                               self.puse = " ".join(cpdict[self.pusekey])
                if oldpuse != self.puse:
                        has_changed = True
                self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file
@@ -5070,13 +5078,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..ab4b88ae91067dfca374ffe3fac6d5053bbe1c7b 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:
@@ -644,7 +647,8 @@ class binarytree(object):
                        use = d["USE"].split()
                        iuse = set(d["IUSE"].split())
                        use = [f for f in use if f in iuse]
-                       del iuse, d["IUSE"]
+                       if not iuse:
+                               del d["IUSE"]
                        use.sort()
                        d["USE"] = " ".join(use)
                        d["DESC"] = d["DESCRIPTION"]
@@ -739,14 +743,16 @@ class binarytree(object):
                        else:
                                writemsg("Resuming download of this tbz2, but it is possible that it is corrupt.\n",
                                        noiselevel=-1)
-               mydest = self.pkgdir + "/All/"
+               mydest = os.path.dirname(self.getname(pkgname))
                try:
                        os.makedirs(mydest, 0775)
                except (OSError, IOError):
                        pass
-               return portage.getbinpkg.file_get(
+               success = portage.getbinpkg.file_get(
                        self.settings["PORTAGE_BINHOST"] + "/" + tbz2name,
                        mydest, fcmd=self.settings["RESUMECOMMAND"])
+               self.inject(pkgname)
+               return success
 
        def getslot(self, mycatpkg):
                "Get a slot for a catpkg; assume it exists."
index 81e767a9c2074f597ea810336266da8e80589704..7c5736a75b75b87c87a847bc03b7c8895a699ead 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)
index 138f1b9848223b8694bde862cbc8e2df0e76e6cb..848e4902e0116fe97aa918b7e49d55877f81614c 100644 (file)
@@ -322,6 +322,8 @@ def get_operator(mydep):
        @return: The operator. One of:
                '~', '=', '>', '<', '=*', '>=', or '<='
        """
+       if mydep:
+               mydep = remove_slot(mydep)
        if mydep[0] == "~":
                operator = "~"
        elif mydep[0] == "=":
@@ -359,6 +361,8 @@ def dep_getcpv(mydep):
        if retval is not None:
                return retval
        mydep_orig = mydep
+       if mydep:
+               mydep = remove_slot(mydep)
        if mydep and mydep[0] == "*":
                mydep = mydep[1:]
        if mydep and mydep[-1] == "*":
@@ -369,9 +373,6 @@ def dep_getcpv(mydep):
                mydep = mydep[2:]
        elif mydep[:1] in "=<>~":
                mydep = mydep[1:]
-       colon = mydep.rfind(":")
-       if colon != -1:
-               mydep = mydep[:colon]
        _dep_getcpv_cache[mydep_orig] = mydep
        return mydep
 
@@ -393,6 +394,12 @@ def dep_getslot(mydep):
                return mydep[colon+1:]
        return None
 
+def remove_slot(mydep):
+       colon = mydep.rfind(":")
+       if colon != -1:
+               mydep = mydep[:colon]
+       return mydep
+
 def dep_getusedeps( depend ):
        """
        Pull a listing of USE Dependencies out of a dep atom.
@@ -596,7 +603,6 @@ def best_match_to_list(mypkg, mylist):
                        if maxvalue < 3:
                                maxvalue = 3
                                bestm = x
-                       continue
                op_val = operator_values[get_operator(x)]
                if op_val > maxvalue:
                        maxvalue = op_val
@@ -629,13 +635,12 @@ def match_from_list(mydep, candidate_list):
 
        mycpv     = dep_getcpv(mydep)
        mycpv_cps = catpkgsplit(mycpv) # Can be None if not specific
-       slot      = None
+       slot      = dep_getslot(mydep)
 
        if not mycpv_cps:
                cat, pkg = catsplit(mycpv)
                ver      = None
                rev      = None
-               slot = dep_getslot(mydep)
        else:
                cat, pkg, ver, rev = mycpv_cps
                if mydep == mycpv:
@@ -654,24 +659,13 @@ def match_from_list(mydep, candidate_list):
 
        if operator is None:
                for x in candidate_list:
-                       xs = pkgsplit(x)
-                       if xs is None:
-                               xcpv = dep_getcpv(x)
-                               if slot is not None:
-                                       xslot = dep_getslot(x)
-                                       if xslot is not None and xslot != slot:
-                                               """  This function isn't given enough information to
-                                               reject atoms based on slot unless *both* compared atoms
-                                               specify slots."""
-                                               continue
-                               if xcpv != mycpv:
-                                       continue
-                       elif xs[0] != mycpv:
+                       if dep_getkey(x) != mycpv:
                                continue
                        mylist.append(x)
 
        elif operator == "=": # Exact match
-               mylist = [cpv for cpv in candidate_list if cpvequal(cpv, mycpv)]
+               mylist = [cpv for cpv in candidate_list if \
+                       cpvequal(remove_slot(cpv), mycpv)]
 
        elif operator == "=*": # glob match
                # XXX: Nasty special casing for leading zeros
@@ -683,7 +677,7 @@ def match_from_list(mydep, candidate_list):
                        myver = "0"+myver
                mycpv = mysplit[0]+"/"+mysplit[1]+"-"+myver
                for x in candidate_list:
-                       xs = catpkgsplit(x)
+                       xs = catpkgsplit(remove_slot(x))
                        myver = xs[2].lstrip("0")
                        if not myver or not myver[0].isdigit():
                                myver = "0"+myver
@@ -693,7 +687,7 @@ def match_from_list(mydep, candidate_list):
 
        elif operator == "~": # version, any revision, match
                for x in candidate_list:
-                       xs = catpkgsplit(x)
+                       xs = catpkgsplit(remove_slot(x))
                        if xs is None:
                                raise InvalidData(x)
                        if not cpvequal(xs[0]+"/"+xs[1]+"-"+xs[2], mycpv_cps[0]+"/"+mycpv_cps[1]+"-"+mycpv_cps[2]):
@@ -706,7 +700,7 @@ def match_from_list(mydep, candidate_list):
                mysplit = ["%s/%s" % (cat, pkg), ver, rev]
                for x in candidate_list:
                        try:
-                               result = pkgcmp(pkgsplit(x), mysplit)
+                               result = pkgcmp(pkgsplit(remove_slot(x)), mysplit)
                        except ValueError: # pkgcmp may return ValueError during int() conversion
                                writemsg("\nInvalid package name: %s\n" % x, noiselevel=-1)
                                raise
@@ -729,5 +723,14 @@ def match_from_list(mydep, candidate_list):
        else:
                raise KeyError("Unknown operator: %s" % mydep)
 
+       if slot is not None:
+               candidate_list = mylist
+               mylist = []
+               for x in candidate_list:
+                       xslot = dep_getslot(x)
+                       if xslot is not None and xslot != slot:
+                               continue
+                       mylist.append(x)
+
        _match_from_list_cache[cache_key] = mylist
-       return mylist
+       return mylist[:]
index b46a00ed22c1129bcd5525e254a5f98000183c5a..f412dd712bdbca4c89827fa8e1e889e4cb4dfd16 100644 (file)
@@ -455,8 +455,8 @@ class ProgressBar(object):
                        self._maxval = maxval
                if value < 0:
                        value = 0
-               elif value > maxval:
-                       value = maxval
+               elif value > self._maxval:
+                       value = self._maxval
                self._curval = value
 
        def inc(self, n=1):
@@ -476,6 +476,7 @@ class TermProgressBar(ProgressBar):
                lines, self.term_columns = get_term_size()
                self.file = sys.stdout
                self._min_columns = 11
+               self._max_columns = 80
                # for indeterminate mode, ranges from 0.0 to 1.0
                self._position = 0.0
 
@@ -490,6 +491,8 @@ class TermProgressBar(ProgressBar):
 
        def _create_image(self):
                cols = self.term_columns
+               if cols > self._max_columns:
+                       cols = self._max_columns
                min_columns = self._min_columns
                curval = self._curval
                maxval = self._maxval