summaryrefslogtreecommitdiff
path: root/pym
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2008-07-15 09:50:41 +0000
committerZac Medico <zmedico@gentoo.org>2008-07-15 09:50:41 +0000
commit34261a71a119e7af9b972238afe7e6532c4a67e3 (patch)
treede5393d9a2caf136cefc2e1c25f0bedda9fcebd3 /pym
parentWhen there is more than one failure, show a summary packages that failed to (diff)
downloadportage-multirepo-34261a71a119e7af9b972238afe7e6532c4a67e3.tar.gz
portage-multirepo-34261a71a119e7af9b972238afe7e6532c4a67e3.tar.bz2
portage-multirepo-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
Diffstat (limited to 'pym')
-rw-r--r--pym/_emerge/__init__.py39
-rw-r--r--pym/portage/elog/__init__.py7
2 files changed, 43 insertions, 3 deletions
diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py
index 78682479..ac21e5f3 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 ea81e841..50a51e9f 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: