Merged from trunk -r11654:11673
authorFabian Groffen <grobian@gentoo.org>
Sat, 11 Oct 2008 15:49:30 +0000 (15:49 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 11 Oct 2008 15:49:30 +0000 (15:49 -0000)
   | 11655    | Before returning config instances from                      |
   | zmedico  | Scheduler._allocate_config(), call the config.reset()       |
   |          | method to make sure all settings from the previous package  |
   |          | get flushed out (such as PORTAGE_LOG_FILE). This fixes a    |
   |          | case where PORTAGE_LOG_FILE leaked from the previous        |
   |          | package to the clean phase of the next one, resulting in an |
   |          | IOError due to the path being invalid and the parent        |
   |          | directory being nonexistent.                                |

   | 11656    | Since EbuildBuild no longer directs it's EbuildFetcher      |
   | zmedico  | instance's output to the global fetch log, there's no need  |
   |          | to schedule it on the fetch queue.                          |

   | 11657    | Use separate temp directories in order to avoid potential   |
   | zmedico  | name collisions.                                            |

   | 11658    | In EbuildBuild._fetch_exit(), clean up the fetch log if     |
   | zmedico  | fetch was successful.                                       |

   | 11659    | Fix apparent breakage from r11593 (slot dep support): *     |
   | zmedico  | Handle KeyError from element.getAttribute() in makeAtom()   |
   |          | and makeVersion(). * Avoid 'sre_constants.error: unmatched  |
   |          | group' exceptions in revisionMatch() when the atom does not |
   |          | have a slot.                                                |

   | 11660    | Don't show the repo display when the merge list is empty.   |
   | zmedico  |                                                             |

   | 11661    | In EbuildFetcher._set_returncode(), don't clean up          |
   | zmedico  | PORTAGE_BUILDDIR if keepwork or keeptemp are in FEATURES.   |

   | 11664    | Bug #240684 - Fix _ebuild_arg_to_phase() to handle the      |
   | zmedico  | src_prepare phase so that the default() function is         |
   |          | properly created.                                           |

   | 11665    | Fix code from previous commit so it properly checks $eapi   |
   | zmedico  | to verify that src_prepare is really a supported phase      |
   |          | function.                                                   |

   | 11666    | Remove redundant os.close(master_fd) call inside            |
   | zmedico  | SpawnProcess._start() since that file discriptor is         |
   |          | referenced by a file object which already has an            |
   |          | appropriate close() call. This fixes an 'IOError: [Errno 9] |
   |          | Bad file descriptor' exception which was raised when        |
   |          | attempting to close the file object.                        |

   | 11667    | At the end of dyn_clean(), also remove the $CATEGORY        |
   | zmedico  | directory if possible.                                      |

   | 11669    | Grab make.globals from GLOBAL_CONFIG_PATH if available and  |
   | zmedico  | fall back to the legacy location if necessary.              |

   | 11670    | Create a new AmbiguousPackageName exception to raise from   |
   | zmedico  | portage.cpv_expand(). It inherits from ValueError, for      |
   |          | backward compatibility with calling code that already       |
   |          | handles ValueError.                                         |

   | 11671    | Bug #241132 - Handle AmbiguousPackageName exceptions for    |
   | zmedico  | atoms passed to the --info action.                          |

   | 11672    | Migrate code from plain ValueError to AmbiguousPackageName  |
   | zmedico  | where appropriate (inherits from ValueError for backward    |
   |          | compatibility).                                             |

   | 11673    | only use dummy echos in do_file() when running in           |
   | SpankMan | interactive mode                                            |

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

bin/doins
bin/ebuild.sh
bin/etc-update
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/exception.py
pym/portage/glsa.py

index 7a97e6f8ba1ec15f39727545e3f359410e15650b..e823da7820878b3842698faaa2a27a3d39f1a96b 100755 (executable)
--- a/bin/doins
+++ b/bin/doins
@@ -25,8 +25,9 @@ if [[ ${INSDESTTREE#${D}} != "${INSDESTTREE}" ]]; then
        exit 1
 fi
 
-TMP=$T/.doins_tmp
-mkdir "$TMP"
+export TMP=$T/.doins_tmp
+# Use separate directories to avoid potential name collisions.
+mkdir -p "$TMP"/{1,2}
 
 if [[ ${INSDESTTREE#${EPREFIX}} != "${INSDESTTREE}" ]]; then
        vecho "-------------------------------------------------------" 1>&2
@@ -42,8 +43,8 @@ _doins() {
        local mysrc="$1" mydir="$2" cleanup="" rval
 
        if [ -L "$mysrc" ] ; then
-               cp "$mysrc" "$TMP"
-               mysrc="$TMP/${mysrc##*/}"
+               cp "$mysrc" "$TMP/2"
+               mysrc="$TMP/2/${mysrc##*/}"
                cleanup=${mysrc}
        fi
 
@@ -85,14 +86,14 @@ for x in "$@" ; do
                        pushd "${PWD%/*}" >/dev/null
                done
                if [[ $x != $x_orig ]] ; then
-                       mv "$x" "$TMP/$x_orig"
-                       pushd "$TMP" >/dev/null
+                       mv "$x" "$TMP/1/$x_orig"
+                       pushd "$TMP/1" >/dev/null
                fi
                find "$x_orig" -type d -exec dodir "${INSDESTTREE}/{}" \;
                find "$x_orig" \( -type f -or -type l \) -print0 | _xdoins
                if [[ $x != $x_orig ]] ; then
                        popd >/dev/null
-                       mv "$TMP/$x_orig" "$x"
+                       mv "$TMP/1/$x_orig" "$x"
                fi
                while popd >/dev/null 2>&1 ; do true ; done
                ((++success))
index 33ba5fae4a0131f9ab48ba92ef4aa808c4e0ad6f..ec8c3ffd009f3515eb31f4a61f62a06ee5125dee 100755 (executable)
@@ -762,8 +762,8 @@ dyn_clean() {
 
        # Some kernels, such as Solaris, return EINVAL when an attempt
        # is made to remove the current working directory.
-       cd "$PORTAGE_BUILDDIR"/..
-       rmdir "$PORTAGE_BUILDDIR" 2>/dev/null
+       cd "$PORTAGE_BUILDDIR"/../..
+       rmdir "$PORTAGE_BUILDDIR" "${PORTAGE_BUILDDIR%/*}" 2>/dev/null
 
        true
 }
@@ -1405,6 +1405,10 @@ _ebuild_arg_to_phase() {
                unpack)
                        phase_func=src_unpack
                        ;;
+               prepare)
+                       ! hasq $eapi 0 1 2_pre1 2_pre2 && \
+                               phase_func=src_prepare
+                       ;;
                configure)
                        ! hasq $eapi 0 1 2_pre1 && \
                                phase_func=src_configure
index 49d971104d1a9c91e0d6e2e8e750993c41932689..ad0419be6dbfe97ad9b1be2b674b743852e20a13 100755 (executable)
@@ -227,7 +227,8 @@ read_int() {
 }
 
 do_file() {
-       echo
+       interactive_echo() { [ "${OVERWRITE_ALL}" != "yes" ] && [ "${DELETE_ALL}" != "yes" ] && echo; }
+       interactive_echo
        local -i my_input
        local -i fcount=0
        until (( $(wc -l < ${TMP}/files/${input}) < 2 )); do
@@ -296,7 +297,7 @@ do_file() {
                        break
                fi
        done
-       echo
+       interactive_echo
        rm ${TMP}/files/${input}
        count=${count}-1
 }
index 77b21bc41cbf7b131f9e17d3a6497c58d191195a..dd45b71b4791851257faa1d7bc43bb0d9d48432a 100644 (file)
@@ -2169,7 +2169,6 @@ class SpawnProcess(SubProcess):
 
                if isinstance(retval, int):
                        # spawn failed
-                       os.close(master_fd)
                        for f in files.values():
                                f.close()
                        self.returncode = retval
@@ -2322,7 +2321,9 @@ class EbuildFetcher(SpawnProcess):
                                        elog_out.close()
                        if not self.prefetch:
                                portage.elog.elog_process(self.pkg.cpv, self._build_dir.settings)
-                       if self.fetchonly or self.returncode == os.EX_OK:
+                       features = self._build_dir.settings.features
+                       if (self.fetchonly or self.returncode == os.EX_OK) and \
+                               not ("keepwork" in features or "keeptemp" in features):
                                try:
                                        shutil.rmtree(self._build_dir.settings["PORTAGE_BUILDDIR"])
                                except EnvironmentError, e:
@@ -2474,20 +2475,13 @@ class EbuildBuild(CompositeTask):
                                self.wait()
                                return
 
-               fetch_log = None
-
                fetcher = EbuildFetcher(config_pool=self.config_pool,
                        fetchall=opts.fetch_all_uri,
                        fetchonly=opts.fetchonly,
-                       background=self.background, logfile=fetch_log,
+                       background=self.background,
                        pkg=pkg, scheduler=self.scheduler)
 
-               if self.background:
-                       fetcher.addExitListener(self._fetch_exit)
-                       self._current_task = fetcher
-                       self.scheduler.fetch.schedule(fetcher)
-               else:
-                       self._start_task(fetcher, self._fetch_exit)
+               self._start_task(fetcher, self._fetch_exit)
 
        def _fetch_exit(self, fetcher):
                opts = self.opts
@@ -2503,6 +2497,13 @@ class EbuildBuild(CompositeTask):
                        os.path.exists(fetcher.logfile):
                        self.settings["PORTAGE_LOG_FILE"] = fetcher.logfile
 
+               if not fetch_failed and fetcher.logfile is not None:
+                       # Fetch was successful, so remove the fetch log.
+                       try:
+                               os.unlink(fetcher.logfile)
+                       except OSError:
+                               pass
+
                if fetch_failed or opts.fetchonly:
                        self.wait()
                        return
@@ -4757,10 +4758,7 @@ class depgraph(object):
 
                                if debug:
                                        print "Exiting...", jbigkey
-               except ValueError, e:
-                       if not e.args or not isinstance(e.args[0], list) or \
-                               len(e.args[0]) < 2:
-                               raise
+               except portage.exception.AmbiguousPackageName, e:
                        pkgs = e.args[0]
                        portage.writemsg("\n\n!!! An atom in the dependencies " + \
                                "is not fully-qualified. Multiple matches:\n\n", noiselevel=-1)
@@ -7507,7 +7505,7 @@ class depgraph(object):
                                                        p.append(colorize("WARN", "    then resume the merge."))
 
                out = sys.stdout
-               show_repos = repoadd_set != set(["0"])
+               show_repos = repoadd_set and repoadd_set != set(["0"])
 
                for x in p:
                        if isinstance(x, basestring):
@@ -8066,8 +8064,8 @@ class depgraph(object):
                                        expanded_atoms = non_virtual_atoms
                        if len(expanded_atoms) > 1:
                                # compatible with portage.cpv_expand()
-                               raise ValueError([portage.dep_getkey(x) \
-                                       for x in expanded_atoms])
+                               raise portage.exception.AmbiguousPackageName(
+                                       [portage.dep_getkey(x) for x in expanded_atoms])
                        if expanded_atoms:
                                atom = expanded_atoms[0]
                        else:
@@ -9970,6 +9968,10 @@ class Scheduler(PollScheduler):
                        temp_settings = self._config_pool[root].pop()
                else:
                        temp_settings = portage.config(clone=self.pkgsettings[root])
+               # Since config.setcpv() isn't guaranteed to call config.reset() due to
+               # performance reasons, call it here to make sure all settings from the
+               # previous package get flushed out (such as PORTAGE_LOG_FILE).
+               temp_settings.reset()
                return temp_settings
 
        def _deallocate_config(self, settings):
@@ -10593,7 +10595,7 @@ def unmerge(root_config, myopts, unmerge_action,
                        # what will and will not get unmerged
                        try:
                                mymatch = vartree.dbapi.match(x)
-                       except ValueError, errpkgs:
+                       except portage.exception.AmbiguousPackageName, errpkgs:
                                print "\n\n!!! The short ebuild name \"" + \
                                        x + "\" is ambiguous.  Please specify"
                                print "!!! one of the following fully-qualified " + \
@@ -11867,7 +11869,7 @@ def action_config(settings, trees, myopts, myfiles):
        print
        try:
                pkgs = trees[settings["ROOT"]]["vartree"].dbapi.match(myfiles[0])
-       except ValueError, e:
+       except portage.exception.AmbiguousPackageName, e:
                # Multiple matches thrown from cpv_expand
                pkgs = e.args[0]
        if len(pkgs) == 0:
@@ -12200,7 +12202,7 @@ def action_depclean(settings, trees, ldpath_mtimes,
                                return
                        try:
                                atom = portage.dep_expand(x, mydb=vardb, settings=settings)
-                       except ValueError, e:
+                       except portage.exception.AmbiguousPackageName, e:
                                msg = "The short ebuild name \"" + x + \
                                        "\" is ambiguous.  Please specify " + \
                                        "one of the following " + \
@@ -14068,10 +14070,6 @@ def emerge_main():
        elif "config"==myaction:
                validate_ebuild_environment(trees)
                action_config(settings, trees, myopts, myfiles)
-       
-       # INFO action
-       elif "info"==myaction:
-               action_info(settings, trees, myopts, myfiles)
 
        # SEARCH action
        elif "search"==myaction:
@@ -14103,7 +14101,7 @@ def emerge_main():
                        if not (buildpkgonly or fetchonly or pretend):
                                post_emerge(root_config, myopts, mtimedb, os.EX_OK)
 
-       elif myaction in ("depclean", "prune"):
+       elif myaction in ("depclean", "info", "prune"):
 
                # Ensure atoms are valid before calling unmerge().
                vardb = trees[settings["ROOT"]]["vartree"].dbapi
@@ -14113,7 +14111,7 @@ def emerge_main():
                                try:
                                        valid_atoms.append(
                                                portage.dep_expand(x, mydb=vardb, settings=settings))
-                               except ValueError, e:
+                               except portage.exception.AmbiguousPackageName, e:
                                        msg = "The short ebuild name \"" + x + \
                                                "\" is ambiguous.  Please specify " + \
                                                "one of the following " + \
@@ -14134,6 +14132,9 @@ def emerge_main():
                                level=logging.ERROR, noiselevel=-1)
                        return 1
 
+               if myaction == "info":
+                       return action_info(settings, trees, myopts, valid_atoms)
+
                validate_ebuild_environment(trees)
                action_depclean(settings, trees, mtimedb["ldpath"],
                        myopts, myaction, valid_atoms, spinner)
index 1c34f44acc1db28327f371b3842a87e5a7f3b446..92ce88f142023050fbfdf6da59f7cf6077bb7a9b 100644 (file)
@@ -1350,8 +1350,11 @@ class config(object):
 
                        # make.globals should not be relative to config_root
                        # because it only contains constants.
-                       self.mygcfg = getconfig(os.path.join(BPREFIX, "etc", "make.globals"),
-                               expand=expand_map)
+                       for x in (portage.const.GLOBAL_CONFIG_PATH, BPREFIX+"/etc"):
+                               self.mygcfg = getconfig(os.path.join(x, "make.globals"),
+                                       expand=expand_map)
+                               if self.mygcfg:
+                                       break
 
                        if self.mygcfg is None:
                                self.mygcfg = {}
@@ -6662,7 +6665,10 @@ def cpv_expand(mycpv, mydb=None, use_cache=1, settings=None):
                                        else:
                                                virtual_name_collision = True
                        if not virtual_name_collision:
-                               raise ValueError, matches
+                               # AmbiguousPackageName inherits from ValueError,
+                               # for backward compatibility with calling code
+                               # that already handles ValueError.
+                               raise portage.exception.AmbiguousPackageName(matches)
                elif matches:
                        mykey=matches[0]
 
index ff34993a6cef092c1f77e4850229c3ab31531b2c..6626fa3bfa8e303f167b8c6b47e059bfadbfbb0a 100644 (file)
@@ -67,6 +67,13 @@ class ReadOnlyFileSystem(PortageException):
 class CommandNotFound(PortageException):
        """A required binary was not available or executable"""
 
+class AmbiguousPackageName(ValueError, PortageException):
+       """Raised by portage.cpv_expand() when the package name is ambiguous due
+       to the existence of multiple matches in different categories. This inherits
+       from ValueError, for backward compatibility with calling code that already
+       handles ValueError."""
+       def __str__(self):
+               return ValueError.__str__(self)
 
 class PortagePackageException(PortageException):
        """Malformed or missing package data"""
index 33d3cf027cf6a796e50eb599d580bc14c19d3708..a16b98c2c040f0fe8890c6c69557bbd60f1987af 100644 (file)
@@ -226,8 +226,13 @@ def makeAtom(pkgname, versionNode):
        rValue = opMapping[versionNode.getAttribute("range")] \
                                + pkgname \
                                + "-" + getText(versionNode, format="strip")
-       if "slot" in versionNode.attributes and versionNode.getAttribute("slot") != "*":
-               rValue += ":"+versionNode.getAttribute("slot")
+       try:
+               slot = versionNode.getAttribute("slot").strip()
+       except KeyError:
+               pass
+       else:
+               if slot and slot != "*":
+                       rValue += ":" + slot
        return str(rValue)
 
 def makeVersion(versionNode):
@@ -243,8 +248,13 @@ def makeVersion(versionNode):
        """
        rValue = opMapping[versionNode.getAttribute("range")] \
                        + getText(versionNode, format="strip")
-       if "slot" in versionNode.attributes and versionNode.getAttribute("slot") != "*":
-               rValue += ":"+versionNode.getAttribute("slot")
+       try:
+               slot = versionNode.getAttribute("slot").strip()
+       except KeyError:
+               pass
+       else:
+               if slot and slot != "*":
+                       rValue += ":" + slot
        return rValue
 
 def match(atom, dbapi, match_type="default"):
@@ -288,9 +298,15 @@ def revisionMatch(revisionAtom, dbapi, match_type="default"):
        @return:        a list with the matching versions
        """
        if match_type == "default" or not hasattr(dbapi, "xmatch"):
-               mylist = dbapi.match(re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:]))
+               if ":" in revisionAtom:
+                       mylist = dbapi.match(re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:]))
+               else:
+                       mylist = dbapi.match(re.sub("-r[0-9]+$", "", revisionAtom[2:]))
        else:
-               mylist = dbapi.xmatch(match_type, re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:]))
+               if ":" in revisionAtom:
+                       mylist = dbapi.xmatch(match_type, re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:]))
+               else:
+                       mylist = dbapi.xmatch(match_type, re.sub("-r[0-9]+$", "", revisionAtom[2:]))
        rValue = []
        for v in mylist:
                r1 = pkgsplit(v)[-1][1:]