Merged from trunk 5336:5350
authorFabian Groffen <grobian@gentoo.org>
Sun, 24 Dec 2006 09:53:02 +0000 (09:53 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sun, 24 Dec 2006 09:53:02 +0000 (09:53 -0000)
For bug #158649, minimize portdb cache pulls for installed packages when
--nodeps is enabled.  This patch also allows the vardb lock to be released
before doing any cache pulls (even when --nodeps is not enabled), and updates
the spinner while the metadata is being pulled.

More intelligently handle CacheCorruption errors in the writable cache.

For bug #158558, ignore invalid depstrings for packages that are being replaced
anyway (otherwise the user would be forced to manually unmerge the package).

When a removal phase fails, tell the user where the ebuild is and advise them
that the ebuild can be removed in order to skip the removal phases.

For installed packages with invalid depstrings, tell the user the location of
the *DEPEND files.

For bug #158632, make aux_get caching safe for missing values in cache entries.

For bug #158658, fix the 'TypeError: int argument required' that happens in the
finalize() routine.

Use the return value from setdefault to avoid an extra dict lookup.

Create a backward compatibility mode for dep_check() so that emerge can use it
to gracefully deal with installed packages that have invalid atoms or dep
syntax.

Make emerge enable backward compatibility mode for dep_check() calls on
installed packages so that it can gracefully invalid atoms or dep syntax.

Fix the "help" phase so that it works without build dirs.

For bug #158649, allow --buildpkgonly to bypass the fakedb population like
--nodeps does.

Revert the default choice for --ask --unmerge (bug #158354) because people are
complaining.

Use a pipe instead of a temp file for the depend phase.

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

bin/ebuild.sh
bin/emerge
pym/cache/metadata_overlay.py
pym/elog_modules/mod_mail_summary.py
pym/portage.py
pym/portage_dep.py

index e9ffea3ddfcd34acf7f052e6a901bea94a239de5..8e8c3dd96f95ee6e65a5a3522b922d2a662f7efa 100755 (executable)
@@ -1759,39 +1759,33 @@ for myarg in ${EBUILD_SH_ARGS} ; do
                export SANDBOX_ON="0"
                set -f
 
-               # Handled in portage.py now
-               #dbkey=${PORTAGE_CACHEDIR}/${CATEGORY}/${PF}
-
-               if [ ! -d "${dbkey%/*}" ]; then
-                       install -d -g ${PORTAGE_GID} -m2775 "${dbkey%/*}"
+               if [ -n "${dbkey}" ] ; then
+                       if [ ! -d "${dbkey%/*}" ]; then
+                               install -d -g ${PORTAGE_GID} -m2775 "${dbkey%/*}"
+                       fi
+                       # Make it group writable. 666&~002==664
+                       umask 002
                fi
 
-               # Make it group writable. 666&~002==664
-               umask 002
+               auxdbkeys="DEPEND RDEPEND SLOT SRC_URI RESTRICT HOMEPAGE LICENSE
+                       DESCRIPTION KEYWORDS INHERITED IUSE CDEPEND PDEPEND PROVIDE EAPI
+                       UNUSED_01 UNUSED_02 UNUSED_03 UNUSED_04 UNUSED_05 UNUSED_06
+                       UNUSED_07"
 
                #the extra $(echo) commands remove newlines
-               echo $(echo "$DEPEND")       > $dbkey
-               echo $(echo "$RDEPEND")     >> $dbkey
-               echo $(echo "$SLOT")        >> $dbkey
-               echo $(echo "$SRC_URI")     >> $dbkey
-               echo $(echo "$RESTRICT")    >> $dbkey
-               echo $(echo "$HOMEPAGE")    >> $dbkey
-               echo $(echo "$LICENSE")     >> $dbkey
-               echo $(echo "$DESCRIPTION") >> $dbkey
-               echo $(echo "$KEYWORDS")    >> $dbkey
-               echo $(echo "$INHERITED")   >> $dbkey
-               echo $(echo "$IUSE")        >> $dbkey
-               echo                       >> $dbkey
-               echo $(echo "$PDEPEND")     >> $dbkey
-               echo $(echo "$PROVIDE")     >> $dbkey
-               echo $(echo "${EAPI:-0}")   >> $dbkey
-               echo $(echo "$UNUSED_01")   >> $dbkey
-               echo $(echo "$UNUSED_02")   >> $dbkey
-               echo $(echo "$UNUSED_03")   >> $dbkey
-               echo $(echo "$UNUSED_04")   >> $dbkey
-               echo $(echo "$UNUSED_05")   >> $dbkey
-               echo $(echo "$UNUSED_06")   >> $dbkey
-               echo $(echo "$UNUSED_07")   >> $dbkey
+               unset CDEPEND
+               [ -n "${EAPI}" ] && EAPI=0
+               if [ -n "${dbkey}" ] ; then
+                       > "${dbkey}"
+                       for f in ${auxdbkeys} ; do
+                               echo $(echo ${!f}) >> "${dbkey}" || exit $?
+                       done
+               else
+                       for f in ${auxdbkeys} ; do
+                               echo $(echo ${!f}) 1>&9 || exit $?
+                       done
+                       9>&-
+               fi
                set +f
                #make sure it is writable by our group:
                exit 0
@@ -1811,7 +1805,9 @@ for myarg in ${EBUILD_SH_ARGS} ; do
 done
 
 # Save the env only for relevant phases.
-if [ -n "$myarg" ] && [ "$myarg" != "clean" ]; then
+if [ -n "${myarg}" ] && \
+       [ "${myarg}" != "clean" ] && \
+       [ "${myarg}" != "help" ] ; then
        # Do not save myarg in the env, or else the above [ -n "$myarg" ] test will
        # give a false positive when ebuild.sh is sourced.
        unset myarg
index 8ffc9bd67c8d47775c7a6a3a389328b9b4f4497e..d005c48597d60e5800c98cbe936ca9e7ac91b5f1 100755 (executable)
@@ -40,6 +40,7 @@ from output import create_color_func
 good = create_color_func("GOOD")
 bad = create_color_func("BAD")
 
+import portage_dep
 import portage_util
 import portage_locks
 import portage_exception
@@ -715,7 +716,6 @@ class FakeVartree(portage.vartree):
                self.root = real_vartree.root
                self.settings = real_vartree.settings
                self.dbapi = portage.fakedbapi(settings=real_vartree.settings)
-               global_updates = None
                vdb_path = os.path.join(self.root, portage.VDB_PATH)
                try:
                        # At least the parent needs to exist for the lock file.
@@ -728,7 +728,6 @@ class FakeVartree(portage.vartree):
                                vdb_lock = portage_locks.lockdir(vdb_path)
                        mykeys = ["SLOT", "COUNTER", "PROVIDE", "USE", "IUSE",
                                "DEPEND", "RDEPEND", "PDEPEND"]
-                       portdb_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
                        real_dbapi = real_vartree.dbapi
                        slot_counters = {}
                        for cpv in real_dbapi.cpv_all():
@@ -746,17 +745,6 @@ class FakeVartree(portage.vartree):
                                                continue
                                slot_counters[myslot_atom] = mycounter
                                self.dbapi.cpv_inject(cpv, metadata=metadata)
-                               try:
-                                       # Use the live ebuild metadata if possible.
-                                       live_metadata = dict(izip(portdb_keys,
-                                               portdb.aux_get(cpv, portdb_keys)))
-                                       self.dbapi.aux_update(cpv, live_metadata)
-                               except (KeyError, portage_exception.PortageException):
-                                       if global_updates is None:
-                                               global_updates = \
-                                                       grab_global_updates(portdb.porttree_root)
-                                       perform_global_updates(
-                                               cpv, self.dbapi, global_updates)
                finally:
                        if vdb_lock:
                                portage_locks.unlockdir(vdb_lock)
@@ -765,6 +753,33 @@ class FakeVartree(portage.vartree):
                        self.settings.treeVirtuals = portage_util.map_dictlist_vals(
                                portage.getCPFromCPV, self.get_all_provides())
 
+               # Intialize variables needed for lazy cache pulls of the live ebuild
+               # metadata.  This ensures that the vardb lock is released ASAP, without
+               # being delayed in case cache generation is triggered.
+               self._aux_get = self.dbapi.aux_get
+               self.dbapi.aux_get = self._aux_get_wrapper
+               self._aux_get_history = set()
+               self._portdb_keys = ["DEPEND", "RDEPEND", "PDEPEND"]
+               self._portdb = portdb
+               self._global_updates = None
+
+       def _aux_get_wrapper(self, pkg, wants):
+               if pkg in self._aux_get_history:
+                       return self._aux_get(pkg, wants)
+               self._aux_get_history.add(pkg)
+               try:
+                       # Use the live ebuild metadata if possible.
+                       live_metadata = dict(izip(self._portdb_keys,
+                               self._portdb.aux_get(pkg, self._portdb_keys)))
+                       self.dbapi.aux_update(pkg, live_metadata)
+               except (KeyError, portage_exception.PortageException):
+                       if self._global_updates is None:
+                               self._global_updates = \
+                                       grab_global_updates(self._portdb.porttree_root)
+                       perform_global_updates(
+                               pkg, self.dbapi, self._global_updates)
+               return self._aux_get(pkg, wants)
+
 def grab_global_updates(portdir):
        from portage_update import grab_updates, parse_updates
        updpath = os.path.join(portdir, "profiles", "updates")
@@ -803,12 +818,16 @@ def show_invalid_depstring_notice(parent_node, depstring, error_msg):
        p_type, p_root, p_key, p_status = parent_node
        msg = []
        if p_status == "nomerge":
+               category, pf = portage.catsplit(p_key)
+               pkg_location = os.path.join(p_root, portage.VDB_PATH, category, pf)
                msg.append("Portage is unable to process the dependencies of the ")
                msg.append("'%s' package. " % p_key)
                msg.append("In order to correct this problem, the package ")
                msg.append("should be uninstalled, reinstalled, or upgraded. ")
                msg.append("As a temporary workaround, the --nodeps option can ")
-               msg.append("be used to ignore all dependencies.")
+               msg.append("be used to ignore all dependencies.  For reference, ")
+               msg.append("the problematic dependencies can be found in the ")
+               msg.append("*DEPEND files located in '%s/'." % pkg_location)
        else:
                msg.append("This package can not be installed.  ")
                msg.append("Please notify the '%s' package maintainer " % p_key)
@@ -859,10 +878,15 @@ class depgraph:
                        # have after new packages have been installed.
                        fakedb = portage.fakedbapi(settings=self.pkgsettings[myroot])
                        self.mydbapi[myroot] = fakedb
-                       for pkg in vardb.cpv_all():
-                               fakedb.cpv_inject(pkg,
-                                       metadata=dict(izip(self._mydbapi_keys,
-                                       vardb.aux_get(pkg, self._mydbapi_keys))))
+                       if "--nodeps" not in self.myopts and \
+                               "--buildpkgonly" not in self.myopts:
+                               # --nodeps bypasses this, since it isn't needed in this case
+                               # and the cache pulls might trigger (slow) cache generation.
+                               for pkg in vardb.cpv_all():
+                                       self.spinner.update()
+                                       fakedb.cpv_inject(pkg,
+                                               metadata=dict(izip(self._mydbapi_keys,
+                                               vardb.aux_get(pkg, self._mydbapi_keys))))
                        del vardb, fakedb
                        self.useFlags[myroot] = {}
                        if "--usepkg" in self.myopts:
@@ -1355,6 +1379,8 @@ class depgraph:
                bindb  = self.trees[myroot]["bintree"].dbapi
                vardb  = self.trees[myroot]["vartree"].dbapi
                pkgsettings = self.pkgsettings[myroot]
+               if myparent:
+                       p_type, p_root, p_key, p_status = myparent
 
                if "--debug" in self.myopts:
                        print
@@ -1367,10 +1393,15 @@ class depgraph:
                #processing dependencies
                """ Call portage.dep_check to evaluate the use? conditionals and make sure all
                dependencies are satisfiable. """
-               mycheck = portage.dep_check(depstring, None,
-                       pkgsettings, myuse=myuse,
-                       use_binaries=("--usepkgonly" in self.myopts),
-                       myroot=myroot, trees=self.trees)
+               try:
+                       if myparent and p_status == "nomerge":
+                               portage_dep._dep_check_strict = False
+                       mycheck = portage.dep_check(depstring, None,
+                               pkgsettings, myuse=myuse,
+                               use_binaries=("--usepkgonly" in self.myopts),
+                               myroot=myroot, trees=self.trees)
+               finally:
+                       portage_dep._dep_check_strict = True
 
                if not mycheck[0]:
                        show_invalid_depstring_notice(myparent, depstring, mycheck[1])
@@ -1586,6 +1617,17 @@ class depgraph:
                        "--nodeps" in self.myopts:
                        return True
 
+               modified_slots = {}
+               for myroot in self.trees:
+                       myslots = {}
+                       modified_slots[myroot] = myslots
+                       final_db = self.mydbapi[myroot]
+                       slot_node_map = self._slot_node_map[myroot]
+                       for slot_atom, mynode in slot_node_map.iteritems():
+                               mytype, myroot, mycpv, mystatus = mynode
+                               if mystatus == "merge":
+                                       myslots[slot_atom] = mycpv
+
                #if "deep" in self.myparams:
                if True:
                        # Pull in blockers from all installed packages that haven't already
@@ -1626,10 +1668,22 @@ class depgraph:
                                                # It is crucial to pass in final_db here in order to
                                                # optimize dep_check calls by eliminating atoms via
                                                # dep_wordreduce and dep_eval calls.
-                                               success, atoms = portage.dep_check(depstr, final_db,
-                                                       pkgsettings, myuse=myuse, trees=dep_check_trees,
-                                                       myroot=myroot)
+                                               try:
+                                                       portage_dep._dep_check_strict = False
+                                                       success, atoms = portage.dep_check(depstr,
+                                                               final_db, pkgsettings, myuse=myuse,
+                                                               trees=dep_check_trees, myroot=myroot)
+                                               finally:
+                                                       portage_dep._dep_check_strict = True
                                                if not success:
+                                                       slot_atom = "%s:%s" % (portage.dep_getkey(pkg),
+                                                               vardb.aux_get(pkg, ["SLOT"])[0])
+                                                       if slot_atom in modified_slots[myroot]:
+                                                               # This package is being replaced anyway, so
+                                                               # ignore invalid dependencies so as not to
+                                                               # annoy the user too much (otherwise they'd be
+                                                               # forced to manually unmerge it first).
+                                                               continue
                                                        show_invalid_depstring_notice(
                                                                ("installed", myroot, pkg, "nomerge"),
                                                                depstr, atoms)
@@ -1650,18 +1704,6 @@ class depgraph:
                                                                self.blocker_parents[blocker] = myparents
                                                        myparents.add(myparent)
 
-               modified_slots = {}
-               if self.blocker_parents:
-                       for myroot in self.trees:
-                               myslots = {}
-                               modified_slots[myroot] = myslots
-                               final_db = self.mydbapi[myroot]
-                               slot_node_map = self._slot_node_map[myroot]
-                               for slot_atom, mynode in slot_node_map.iteritems():
-                                       mytype, myroot, mycpv, mystatus = mynode
-                                       if mystatus == "merge":
-                                               modified_slots[myroot][slot_atom] = mycpv
-
                for blocker in self.blocker_parents.keys():
                        mytype, myroot, mydep = blocker
                        initial_db = self.trees[myroot]["vartree"].dbapi
@@ -3184,8 +3226,7 @@ def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
                #we're done... return
                return 0
        if "--ask" in myopts:
-               if userquery("Would you like to unmerge these packages?",
-                       responses=["No", "Yes"], colours=[red, green]) == "No":
+               if userquery("Would you like to unmerge these packages?")=="No":
                        # enter pretend mode for correct formatting of results
                        myopts["--pretend"] = True
                        print
@@ -3206,11 +3247,32 @@ def unmerge(settings, myopts, vartree, unmerge_action, unmerge_files,
                                vartree=vartree, ldpath_mtimes=ldpath_mtimes)
                        if retval != os.EX_OK:
                                emergelog(xterm_titles, " !!! unmerge FAILURE: "+y)
+                               ebuild = vartree.dbapi.findname(y)
+                               show_unmerge_failure_message(y, ebuild, retval)
+                               sys.exit(retval)
                        else:
                                clean_world(vartree.dbapi, y)
                                emergelog(xterm_titles, " >>> unmerge success: "+y)
        return 1
 
+def show_unmerge_failure_message(pkg, ebuild, retval):
+
+       from formatter import AbstractFormatter, DumbWriter
+       f = AbstractFormatter(DumbWriter(maxcol=72))
+
+       msg = []
+       msg.append("A removal phase of the '%s' package " % pkg)
+       msg.append("has failed with exit value %s.  " % retval)
+       msg.append("The problem occurred while executing ")
+       msg.append("the ebuild located at '%s'.  " % ebuild)
+       msg.append("If necessary, manually remove the ebuild " )
+       msg.append("in order to skip the execution of removal phases.")
+
+       print
+       for x in msg:
+               f.add_flowing_data(x)
+       f.end_paragraph(1)
+
 def chk_updated_info_files(root, infodirs, prev_mtimes, retval):
 
        print
@@ -4227,8 +4289,12 @@ def action_depclean(settings, trees, ldpath_mtimes,
                                        else:
                                                print "hard"
 
-                               success, atoms = portage.dep_check(depstr, None, settings,
-                                       myuse=usedef, trees=dep_check_trees, myroot=myroot)
+                               try:
+                                       portage_dep._dep_check_strict = False
+                                       success, atoms = portage.dep_check(depstr, None, settings,
+                                               myuse=usedef, trees=dep_check_trees, myroot=myroot)
+                               finally:
+                                       portage_dep._dep_check_strict = True
                                if not success:
                                        show_invalid_depstring_notice(
                                                ("installed", myroot, pkg, "nomerge"),
@@ -4329,12 +4395,11 @@ def action_build(settings, trees, mtimedb,
                        sys.exit(0)
 
                myparams = create_depgraph_params(myopts, myaction)
-               mydepgraph = depgraph(settings, trees,
-                       myopts, myparams, spinner)
                if myaction in ["system","world"]:
                        if not ("--quiet" in myopts):
                                print "Calculating",myaction,"dependencies  ",
                                sys.stdout.flush()
+                       mydepgraph = depgraph(settings, trees, myopts, myparams, spinner)
                        if not mydepgraph.xcreate(myaction):
                                print "!!! Depgraph creation failed."
                                sys.exit(1)
@@ -4344,6 +4409,7 @@ def action_build(settings, trees, mtimedb,
                        if not ("--quiet" in myopts):
                                print "Calculating dependencies  ",
                                sys.stdout.flush()
+                       mydepgraph = depgraph(settings, trees, myopts, myparams, spinner)
                        try:
                                retval, favorites = mydepgraph.select_files(myfiles)
                        except portage_exception.PackageNotFound, e:
index 1716e3dd45966d6aaeee4794944f37ab5f3c40fb..24ab16349f3081db5e26d0ecb952faa75ec57af6 100644 (file)
@@ -6,6 +6,7 @@ import time
 if not hasattr(__builtins__, "set"):
        from sets import Set as set
 from cache import template
+from cache.cache_errors import CacheCorruption
 from cache.flat_hash import database as db_rw
 from cache.metadata import database as db_ro
 
@@ -25,6 +26,9 @@ class database(template.database):
                        value = self.db_rw[cpv]
                except KeyError:
                        return self.db_ro[cpv] # raises a KeyError when necessary
+               except CacheCorruption:
+                       del self.db_rw[cpv]
+                       return self.db_ro[cpv] # raises a KeyError when necessary
                if self._is_whiteout(value):
                        if self._is_whiteout_valid(cpv, value):
                                raise KeyError(cpv)
index 53628b9204cbab635b3e1c1212cc107efd64e74a..5e642f418da6e65cf4396f349bda2475a4cced42 100644 (file)
@@ -29,7 +29,8 @@ def finalize(mysettings):
        mysubject = mysubject.replace("${PACKAGE}", count)
        mysubject = mysubject.replace("${HOST}", socket.getfqdn())
 
-       mybody = "elog messages for the following packages generated by process %d on host %s:\n" % (count, os.getpid(), socket.getfqdn())
+       mybody = "elog messages for the following packages generated by " + \
+               "process %d on host %s:\n" % (os.getpid(), socket.getfqdn())
        for cpv in _items.keys():
                 mybody += "- %s\n" % cpv
 
index 69845e12d8787d0ccc82747e922e7dbc8b0eb84a..43787bbe103ea10bb36f0087340c5d83ec7dc3f1 100644 (file)
@@ -1997,7 +1997,7 @@ class config:
 
 # XXX This would be to replace getstatusoutput completely.
 # XXX Issue: cannot block execution. Deadlock condition.
-def spawn(mystring,mysettings,debug=0,free=0,droppriv=0,sesandbox=0,fd_pipes=None,**keywords):
+def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, **keywords):
        """spawn a subprocess with optional sandbox protection,
        depending on whether sandbox is enabled.  The "free" argument,
        when set to 1, will disable sandboxing.  This allows us to
@@ -3123,7 +3123,32 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                # get possible slot information from the deps file
                if mydo == "depend":
                        writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2)
-                       if dbkey:
+                       if isinstance(dbkey, dict):
+                               mysettings["dbkey"] = ""
+                               pr, pw = os.pipe()
+                               fd_pipes = {0:0, 1:1, 2:2, 9:pw}
+                               mypids = spawn(EBUILD_SH_BINARY + " depend", mysettings,
+                                       fd_pipes=fd_pipes, returnpid=True)
+                               os.close(pw) # belongs exclusively to the child process now
+                               maxbytes = 1024
+                               mybytes = []
+                               while True:
+                                       mybytes.append(os.read(pr, maxbytes))
+                                       if not mybytes[-1]:
+                                               break
+                               os.close(pr)
+                               mybytes = "".join(mybytes)
+                               global auxdbkeys
+                               dbkey.update(izip(auxdbkeys, mybytes.split("\n")))
+                               retval = os.waitpid(mypids[0], 0)[1]
+                               # If it got a signal, return the signal that was sent, but
+                               # shift in order to distinguish it from a return value. (just
+                               # like portage_exec.spawn() would do).
+                               if retval & 0xff:
+                                       return (retval & 0xff) << 8
+                               # Otherwise, return its exit code.
+                               return retval >> 8
+                       elif dbkey:
                                mysettings["dbkey"] = dbkey
                        else:
                                mysettings["dbkey"] = \
@@ -3141,7 +3166,7 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0,
                        return 1
 
                # Build directory creation isn't required for any of these.
-               if mydo not in ["fetch","digest","manifest"]:
+               if mydo not in ("digest", "fetch", "help", "manifest"):
                        mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
                        if mystatus:
                                return mystatus
@@ -3588,11 +3613,12 @@ def unmerge(cat, pkg, myroot, mysettings, mytrimworld=1, vartree=None, ldpath_mt
        try:
                mylink.lockdb()
                if mylink.exists():
-                       mylink.unmerge(trimworld=mytrimworld, cleanup=1,
+                       retval = mylink.unmerge(trimworld=mytrimworld, cleanup=1,
                                ldpath_mtimes=ldpath_mtimes)
-                       mylink.delete()
-                       return 0
-               return 1
+                       if retval == os.EX_OK:
+                               mylink.delete()
+                       return retval
+               return os.EX_OK
        finally:
                mylink.unlockdb()
 
@@ -3653,7 +3679,8 @@ def _expand_new_virtuals(mysplit, edebug, mydbapi, mysettings, myroot="/",
                        newsplit.append(_expand_new_virtuals(x, edebug, mydbapi,
                                mysettings, myroot=myroot, trees=trees, **kwargs))
                        continue
-               if not isvalidatom(x, allow_blockers=True):
+               if portage_dep._dep_check_strict and \
+                       not isvalidatom(x, allow_blockers=True):
                        raise portage_exception.ParseError(
                                "invalid atom: '%s'" % x)
                mykey = dep_getkey(x)
@@ -5342,55 +5369,13 @@ class portdbapi(dbapi):
                        writemsg("doregen: %s %s\n" % (doregen,mycpv), 2)
                        writemsg("Generating cache entry(0) for: "+str(myebuild)+"\n",1)
 
-                       if self.tmpfs:
-                               mydbkey = self.tmpfs+"/aux_db_key_temp"
-                       else:
-                               mydbkey = self.depcachedir+"/aux_db_key_temp"
-
-                       mylock = None
-                       try:
-                               mylock = portage_locks.lockfile(mydbkey, wantnewlockfile=1)
-                               try:
-                                       os.unlink(mydbkey)
-                               except (IOError, OSError), e:
-                                       if e.errno != errno.ENOENT:
-                                               raise
-                                       del e
-
-                               self.doebuild_settings.reset()
-                               myret = doebuild(myebuild, "depend", "/",
-                                        self.doebuild_settings, dbkey=mydbkey, tree="porttree",
-                                        mydbapi=self)
-                               if myret != os.EX_OK:
-                                       #depend returned non-zero exit code...
-                                       writemsg((red("\naux_get():") + \
-                                               " (0) Error in '%s'. (%s)\n" + \
-                                               "               Check for syntax error or " + \
-                                               "corruption in the ebuild. (--debug)\n\n") % \
-                                               (myebuild, myret), noiselevel=-1)
-                                       raise KeyError(mycpv)
-
-                               try:
-                                       mycent = open(mydbkey, "r")
-                                       os.unlink(mydbkey)
-                                       mylines = mycent.readlines()
-                                       mycent.close()
-                               except (IOError, OSError):
-                                       writemsg((red("\naux_get():") + \
-                                               " (1) Error in '%s' ebuild.\n" + \
-                                               "               Check for syntax error or " + \
-                                               "corruption in the ebuild. (--debug)\n\n") % myebuild,
-                                               noiselevel=-1)
-                                       raise KeyError(mycpv)
-                       finally:
-                               if mylock:
-                                       portage_locks.unlockfile(mylock)
-
+                       self.doebuild_settings.reset()
                        mydata = {}
-                       for x in range(0,len(mylines)):
-                               if mylines[x][-1] == '\n':
-                                       mylines[x] = mylines[x][:-1]
-                               mydata[auxdbkeys[x]] = mylines[x]
+                       myret = doebuild(myebuild, "depend",
+                               self.doebuild_settings["ROOT"], self.doebuild_settings,
+                               dbkey=mydata, tree="porttree", mydbapi=self)
+                       if myret != os.EX_OK:
+                               raise KeyError(mycpv)
 
                        if "EAPI" not in mydata or not mydata["EAPI"].strip():
                                mydata["EAPI"] = "0"
@@ -5428,10 +5413,10 @@ class portdbapi(dbapi):
 
                if cache_me:
                        aux_cache = {}
+                       if not mydata.setdefault("EAPI", "0"):
+                               mydata["EAPI"] = "0"
                        for x in self._aux_cache_keys:
-                               aux_cache[x] = mydata[x]
-                       if not aux_cache["EAPI"]:
-                               aux_cache["EAPI"] = "0"
+                               aux_cache[x] = mydata.get(x, "")
                        self._aux_cache[mycpv] = aux_cache
 
                return returnme
@@ -6387,7 +6372,7 @@ class dblink:
                                # XXX: Decide how to handle failures here.
                                if retval != os.EX_OK:
                                        writemsg("!!! FAILED prerm: %s\n" % retval, noiselevel=-1)
-                                       sys.exit(123)
+                                       return retval
 
                        self._unmerge_pkgfiles(pkgfiles)
 
@@ -6402,7 +6387,7 @@ class dblink:
                                # XXX: Decide how to handle failures here.
                                if retval != os.EX_OK:
                                        writemsg("!!! FAILED postrm: %s\n" % retval, noiselevel=-1)
-                                       sys.exit(123)
+                                       return retval
                                doebuild(myebuildpath, "cleanrm", self.myroot, self.settings,
                                        tree="vartree", mydbapi=self.vartree.dbapi,
                                        vartree=self.vartree)
@@ -6425,6 +6410,7 @@ class dblink:
                                        portage_locks.unlockdir(catdir_lock)
                env_update(target_root=self.myroot, prev_mtimes=ldpath_mtimes,
                        contents=contents)
+               return os.EX_OK
 
        def _unmerge_pkgfiles(self, pkgfiles):
 
index feb499cf0256a959b1bcd590cb0cc42760b39e74..8f7ed0051621e8657b580f5e54d72f7eabeda1a9 100644 (file)
@@ -103,6 +103,11 @@ def paren_enclose(mylist):
                        mystrparts.append(x)
        return " ".join(mystrparts)
 
+# This is just for use by emerge so that it can enable a backward compatibility
+# mode in order to gracefully deal with installed packages that have invalid
+# atoms or dep syntax.
+_dep_check_strict = True
+
 def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]):
        """
        Takes a paren_reduce'd array and reduces the use? conditionals out
@@ -127,6 +132,8 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]):
        if deparray and deparray[-1] and deparray[-1][-1] == "?":
                raise portage_exception.InvalidDependString("Conditional without target in \""+paren_enclose(deparray)+"\"")
 
+       global _dep_check_strict
+
        mydeparray = deparray[:]
        rlist = []
        while mydeparray:
@@ -186,6 +193,9 @@ def use_reduce(deparray, uselist=[], masklist=[], matchall=0, excludeall=[]):
                                                additions = use_reduce(target, uselist, masklist, matchall, excludeall)
                                                if additions:
                                                        rlist.append(additions)
+                                       elif not _dep_check_strict:
+                                               # The old deprecated behavior.
+                                               rlist.append(target)
                                        else:
                                                raise portage_exception.InvalidDependString(
                                                        "Conditional without parenthesis: '%s?'" % head)