diff options
author | Zac Medico <zmedico@gentoo.org> | 2008-07-15 09:50:41 +0000 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2008-07-15 09:50:41 +0000 |
commit | 34261a71a119e7af9b972238afe7e6532c4a67e3 (patch) | |
tree | de5393d9a2caf136cefc2e1c25f0bedda9fcebd3 | |
parent | 3228fd7b4de8d850b3c943fc84fb61ae8bc715eb (diff) | |
download | portage-34261a71a119e7af9b972238afe7e6532c4a67e3.tar.gz portage-34261a71a119e7af9b972238afe7e6532c4a67e3.tar.bz2 portage-34261a71a119e7af9b972238afe7e6532c4a67e3.zip |
When packages fail with --jobs > 1 and the "echo" elog module is not enabled,
emulate elog's mod_echo module to show the 'error' level messages, which should
include the important die message. This is implemented by adding a private
hook inside elog_process() which the scheduler uses to collect error messages.
svn path=/main/trunk/; revision=11056
-rw-r--r-- | pym/_emerge/__init__.py | 39 | ||||
-rw-r--r-- | pym/portage/elog/__init__.py | 7 |
2 files changed, 43 insertions, 3 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index 786824790..ac21e5f3f 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -8391,6 +8391,7 @@ class Scheduler(PollScheduler): self._completed_tasks = set() self._failed_pkgs = [] self._failed_pkgs_all = [] + self._failed_pkgs_die_msgs = [] self._failed_fetches = [] self._parallel_fetch = False merge_count = len([x for x in mergelist \ @@ -8847,6 +8848,29 @@ class Scheduler(PollScheduler): self._logger.log(" *** Finished. Cleaning up...") + background = self._max_jobs > 1 + if self._failed_pkgs_all and background and \ + self._failed_pkgs_die_msgs and \ + not _flush_elog_mod_echo(): + + printer = portage.output.EOutput() + for mysettings, key, logentries in self._failed_pkgs_die_msgs: + root_msg = "" + if mysettings["ROOT"] != "/": + root_msg = " merged to %s" % mysettings["ROOT"] + print + printer.einfo("Error messages for package %s%s:" % \ + (colorize("INFORM", key), root_msg)) + print + for phase in portage.const.EBUILD_PHASES: + if phase not in logentries: + continue + for msgtype, msgcontent in logentries[phase]: + if isinstance(msgcontent, basestring): + msgcontent = [msgcontent] + for line in msgcontent: + printer.eerror(line.strip("\n")) + if len(self._failed_pkgs_all) > 1: _flush_elog_mod_echo() msg = "The following packages have " + \ @@ -8865,6 +8889,12 @@ class Scheduler(PollScheduler): return rval + def _elog_listener(self, mysettings, key, logentries, fulltext): + errors = portage.elog.filter_loglevels(logentries, ["ERROR"]) + if errors: + self._failed_pkgs_die_msgs.append( + (mysettings, key, errors)) + def _add_packages(self): pkg_queue = self._pkg_queue for pkg in self._mergelist: @@ -8928,14 +8958,14 @@ class Scheduler(PollScheduler): self._add_packages() pkg_queue = self._pkg_queue failed_pkgs = self._failed_pkgs + portage.elog._emerge_elog_listener = self._elog_listener rval = os.EX_OK try: self._main_loop() finally: self._main_loop_cleanup() - # discard any failures and return the - # exist status of the last one + portage.elog._emerge_elog_listener = None if failed_pkgs: pkg, rval = failed_pkgs[-1] @@ -9905,13 +9935,18 @@ def _flush_elog_mod_echo(): """ Dump the mod_echo output now so that our other notifications are shown last. + @rtype: bool + @returns: True if messages were shown, False otherwise. """ + messages_shown = False try: from portage.elog import mod_echo except ImportError: pass # happens during downgrade to a version without the module else: + messages_shown = bool(mod_echo._items) mod_echo.finalize() + return messages_shown def post_emerge(trees, mtimedb, retval): """ diff --git a/pym/portage/elog/__init__.py b/pym/portage/elog/__init__.py index ea81e8411..50a51e9fd 100644 --- a/pym/portage/elog/__init__.py +++ b/pym/portage/elog/__init__.py @@ -53,10 +53,11 @@ def _load_mod(name): _elog_mod_imports[name] = m return m +_emerge_elog_listener = None _elog_atexit_handlers = [] _preserve_logentries = {} def elog_process(cpv, mysettings, phasefilter=None): - global _elog_atexit_handlers, _preserve_logentries + global _elog_atexit_handlers, _emerge_elog_listener, _preserve_logentries logsystems = mysettings.get("PORTAGE_ELOG_SYSTEM","").split() for s in logsystems: @@ -100,6 +101,10 @@ def elog_process(cpv, mysettings, phasefilter=None): default_fulllog = _combine_logentries(default_logentries) + if _emerge_elog_listener is not None: + _emerge_elog_listener(mysettings, str(key), + default_logentries, default_fulllog) + # pass the processing to the individual modules logsystems = mysettings["PORTAGE_ELOG_SYSTEM"].split() for s in logsystems: |