Exception logs now contain the last 10 messages emitted by Sphinx.

This commit is contained in:
Georg Brandl 2014-09-17 12:22:14 +02:00
parent 294c83d8f0
commit 9f0afa534d
5 changed files with 28 additions and 7 deletions

View File

@ -1,6 +1,11 @@
Release 1.2.4 (in development) Release 1.2.4 (in development)
============================== ==============================
Features added
--------------
* Exception logs now contain the last 10 messages emitted by Sphinx.
Release 1.2.3 (released Sep 1, 2014) Release 1.2.3 (released Sep 1, 2014)
==================================== ====================================

View File

@ -17,6 +17,7 @@ import types
import posixpath import posixpath
from os import path from os import path
from cStringIO import StringIO from cStringIO import StringIO
from collections import deque
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import convert_directive_function, \ from docutils.parsers.rst import convert_directive_function, \
@ -95,6 +96,9 @@ class Sphinx(object):
self._events = events.copy() self._events = events.copy()
# keep last few messages for traceback
self.messagelog = deque(maxlen=10)
# say hello to the world # say hello to the world
self.info(bold('Running Sphinx v%s' % sphinx.__version__)) self.info(bold('Running Sphinx v%s' % sphinx.__version__))
@ -241,6 +245,7 @@ class Sphinx(object):
wfile.write('\n') wfile.write('\n')
if hasattr(wfile, 'flush'): if hasattr(wfile, 'flush'):
wfile.flush() wfile.flush()
self.messagelog.append(message)
def warn(self, message, location=None, prefix='WARNING: '): def warn(self, message, location=None, prefix='WARNING: '):
"""Emit a warning. """Emit a warning.

View File

@ -277,8 +277,8 @@ class Builder(object):
# finish (write static files etc.) # finish (write static files etc.)
self.finish() self.finish()
status = (self.app.statuscode == 0 and 'succeeded' status = (self.app.statuscode == 0
or 'finished with problems') and 'succeeded' or 'finished with problems')
if self.app._warncount: if self.app._warncount:
self.info(bold('build %s, %s warning%s.' % self.info(bold('build %s, %s warning%s.' %
(status, self.app._warncount, (status, self.app._warncount,
@ -387,7 +387,7 @@ class Builder(object):
threads.append(t) threads.append(t)
# make sure all threads have finished # make sure all threads have finished
self.info(bold('waiting for workers... '))#, nonl=True) self.info(bold('waiting for workers... '))
for t in threads: for t in threads:
t.join() t.join()

View File

@ -12,7 +12,6 @@
import os import os
import re import re
import sys import sys
import shutil
import fnmatch import fnmatch
import tempfile import tempfile
import posixpath import posixpath
@ -30,6 +29,7 @@ import jinja2
import sphinx import sphinx
from sphinx.errors import PycodeError from sphinx.errors import PycodeError
from sphinx.util.pycompat import bytes from sphinx.util.pycompat import bytes
from sphinx.util.console import strip_colors
# import other utilities; partly for backwards compatibility, so don't # import other utilities; partly for backwards compatibility, so don't
# prune unused ones indiscriminately # prune unused ones indiscriminately
@ -176,6 +176,8 @@ _DEBUG_HEADER = '''\
# Python version: %s # Python version: %s
# Docutils version: %s %s # Docutils version: %s %s
# Jinja2 version: %s # Jinja2 version: %s
# Last messages:
%s
# Loaded extensions: # Loaded extensions:
''' '''
@ -184,11 +186,17 @@ def save_traceback(app):
import platform import platform
exc = traceback.format_exc() exc = traceback.format_exc()
fd, path = tempfile.mkstemp('.log', 'sphinx-err-') fd, path = tempfile.mkstemp('.log', 'sphinx-err-')
last_msgs = ''
if app is not None:
last_msgs = '\n'.join(
'# %s' % strip_colors(force_decode(s, 'utf-8')).strip()
for s in app.messagelog)
os.write(fd, (_DEBUG_HEADER % os.write(fd, (_DEBUG_HEADER %
(sphinx.__version__, (sphinx.__version__,
platform.python_version(), platform.python_version(),
docutils.__version__, docutils.__version_details__, docutils.__version__, docutils.__version_details__,
jinja2.__version__)).encode('utf-8')) jinja2.__version__,
last_msgs)).encode('utf-8'))
if app is not None: if app is not None:
for extname, extmod in app._extensions.iteritems(): for extname, extmod in app._extensions.iteritems():
os.write(fd, ('# %s from %s\n' % ( os.write(fd, ('# %s from %s\n' % (

View File

@ -63,6 +63,9 @@ def coloron():
def colorize(name, text): def colorize(name, text):
return codes.get(name, '') + text + codes.get('reset', '') return codes.get(name, '') + text + codes.get('reset', '')
def strip_colors(s):
return re.compile('\x1b.*?m').sub('', s)
def create_color_func(name): def create_color_func(name):
def inner(text): def inner(text):
return colorize(name, text) return colorize(name, text)