From a07e7ad534d798d778a72ff80b6c838c0c1cf07e Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Fri, 20 Feb 2009 11:01:46 +0100 Subject: [PATCH] #62: There is now a ``-w`` option for sphinx-build that writes warnings to a file, in addition to stderr. --- CHANGES | 3 +++ doc/intro.rst | 3 +++ doc/sphinx-build.1 | 6 +++++ sphinx/cmdline.py | 51 ++++++++++++++++++++++++----------------- sphinx/util/__init__.py | 13 +++++++++++ 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 13d835d2e..7b54115bc 100644 --- a/CHANGES +++ b/CHANGES @@ -160,6 +160,9 @@ New features added - Quickstart can now generate a Windows ``make.bat`` file. + - #62: There is now a ``-w`` option for sphinx-build that writes + warnings to a file, in addition to stderr. + - There is now a ``-W`` option for sphinx-build that turns warnings into errors. diff --git a/doc/intro.rst b/doc/intro.rst index 4306a44fc..7b8f86511 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -139,6 +139,9 @@ The :program:`sphinx-build` script has several more options: Do not output anything on standard output, also suppress warnings. Only errors are written to standard error. +**-w** *file* + Write warnings (and errors) to the given file, in addition to standard error. + **-W** Turn warnings into errors. This means that the build stops at the first warning and ``sphinx-build`` exits with exit status 1. diff --git a/doc/sphinx-build.1 b/doc/sphinx-build.1 index 16f8bd34e..498771c92 100644 --- a/doc/sphinx-build.1 +++ b/doc/sphinx-build.1 @@ -84,6 +84,12 @@ Quiet operation, just prints warnings and errors on stderr. \fB-Q\fR Very quiet operation, doesn't print anything except for errors. .TP +\fB-w\fR +Write warnings and errors into the given file, in addition to stderr. +.TP +\fB-W\fR +Turn warnings into errors. +.TP \fB-P\fR Runs Pdb on exception. .SH "SEE ALSO" diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index cdceac6e3..cd2c4008d 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -19,7 +19,7 @@ from docutils.utils import SystemMessage from sphinx import __version__ from sphinx.application import Sphinx, SphinxError -from sphinx.util import format_exception_cut_frames, save_traceback +from sphinx.util import Tee, format_exception_cut_frames, save_traceback from sphinx.util.console import darkred, nocolor, color_terminal @@ -45,6 +45,7 @@ new and changed files -N -- do not do colored output -q -- no output on stdout, just warnings on stderr -Q -- no output at all, not even warnings + -w -- write warnings (and errors) to given file -W -- turn warnings into errors -P -- run Pdb on exception Modi: @@ -59,7 +60,7 @@ def main(argv): nocolor() try: - opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:NEqQWP') + opts, args = getopt.getopt(argv[1:], 'ab:t:d:c:CD:A:NEqQWw:P') allopts = set(opt[0] for opt in opts) srcdir = confdir = path.abspath(args[0]) if not path.isdir(srcdir): @@ -91,6 +92,8 @@ def main(argv): freshenv = warningiserror = use_pdb = False status = sys.stdout warning = sys.stderr + error = sys.stderr + warnfile = None confoverrides = {} htmlcontext = {} tags = [] @@ -150,10 +153,17 @@ def main(argv): warning = None elif opt == '-W': warningiserror = True + elif opt == '-w': + warnfile = val elif opt == '-P': use_pdb = True confoverrides['html_context'] = htmlcontext + if warning and warnfile: + warnfp = open(warnfile, 'w') + warning = Tee(warning, warnfp) + error = warning + try: app = Sphinx(srcdir, confdir, outdir, doctreedir, buildername, confoverrides, status, warning, freshenv, @@ -163,36 +173,35 @@ def main(argv): except KeyboardInterrupt: if use_pdb: import pdb - print >>sys.stderr, darkred('Interrupted while building, ' - 'starting debugger:') + print >>error, darkred('Interrupted while building, ' + 'starting debugger:') traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) return 1 except Exception, err: if use_pdb: import pdb - print >>sys.stderr, darkred('Exception occurred while building, ' - 'starting debugger:') + print >>error, darkred('Exception occurred while building, ' + 'starting debugger:') traceback.print_exc() pdb.post_mortem(sys.exc_info()[2]) else: if isinstance(err, SystemMessage): - print >>sys.stderr, darkred('reST markup error:') - print >>sys.stderr, err.args[0].encode('ascii', - 'backslashreplace') + print >>error, darkred('reST markup error:') + print >>error, err.args[0].encode('ascii', 'backslashreplace') elif isinstance(err, SphinxError): - print >>sys.stderr, darkred('%s:' % err.category) - print >>sys.stderr, err + print >>error, darkred('%s:' % err.category) + print >>error, err else: - print >>sys.stderr, darkred('Exception occurred:') - print >>sys.stderr, format_exception_cut_frames().rstrip() + print >>error, darkred('Exception occurred:') + print >>error, format_exception_cut_frames().rstrip() tbpath = save_traceback() - print >>sys.stderr, darkred('The full traceback has been saved ' - 'in %s, if you want to report the ' - 'issue to the author.' % tbpath) - print >>sys.stderr, ('Please also report this if it was a user ' - 'error, so that a better error message ' - 'can be provided next time.') - print >>sys.stderr, ('Send reports to ' - 'sphinx-dev@googlegroups.com. Thanks!') + print >>error, darkred('The full traceback has been saved ' + 'in %s, if you want to report the ' + 'issue to the author.' % tbpath) + print >>error, ('Please also report this if it was a user ' + 'error, so that a better error message ' + 'can be provided next time.') + print >>error, ('Send reports to sphinx-dev@googlegroups.com. ' + 'Thanks!') return 1 diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 20854af35..e02fd1b74 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -295,6 +295,19 @@ def ustrftime(format, *args): return time.strftime(unicode(format).encode('utf-8'), *args).decode('utf-8') +class Tee(object): + """ + File-like object writing to two streams. + """ + def __init__(self, stream1, stream2): + self.stream1 = stream1 + self.stream2 = stream2 + + def write(self, text): + self.stream1.write(text) + self.stream2.write(text) + + class FilenameUniqDict(dict): """ A dictionary that automatically generates unique names for its keys,