summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Domke <mdomke@jackbird.local>2016-07-26 15:57:13 +0200
committerMartin Domke <mdomke@jackbird.local>2016-07-26 15:57:13 +0200
commitc782060a0620135b01eb64e15508cca581cb09be (patch)
tree36feb56558630a3b5727485150b3709efa6d2d4b
parentf82b5d62d0c4e48b95466bb259f3401aecf28de7 (diff)
downloadflake8-c782060a0620135b01eb64e15508cca581cb09be.tar.gz
Add --tee option to split report output stream.
The --tee option allows the linter report to be written to stdout, even though it is being redirected to a file with the --output-file option. This is useful if I want to store the report in a separate file for later analysis but also be able to print the output on screen (e.g when running in a CI environment).
-rw-r--r--docs/source/user/invocation.rst1
-rw-r--r--docs/source/user/options.rst20
-rw-r--r--src/flake8/formatting/base.py2
-rw-r--r--src/flake8/main/options.py6
-rw-r--r--tests/unit/test_base_formatter.py21
5 files changed, 43 insertions, 7 deletions
diff --git a/docs/source/user/invocation.rst b/docs/source/user/invocation.rst
index 383e93a..d96d0f9 100644
--- a/docs/source/user/invocation.rst
+++ b/docs/source/user/invocation.rst
@@ -125,6 +125,7 @@ And you should see something like:
available to use. (Default: auto)
--output-file=OUTPUT_FILE
Redirect report to a file.
+ --tee Write to stdout and output-file.
--append-config=APPEND_CONFIG
Provide extra config files to parse in addition to the
files found by Flake8 by default. These files are the
diff --git a/docs/source/user/options.rst b/docs/source/user/options.rst
index acaa67c..78bab1c 100644
--- a/docs/source/user/options.rst
+++ b/docs/source/user/options.rst
@@ -563,6 +563,26 @@
output_file = output.txt
+.. option:: --tee
+
+ Also print output to stdout if output-file has ben configured.
+
+ Command-line example:
+
+ .. prompt:: bash
+
+ flake8 --tee --output-file=output.txt dir/
+
+ This **can** be specified in config files.
+
+ Example config file usage:
+
+ .. code-block:: ini
+
+ output-file = output.txt
+ tee = True
+
+
.. option:: --append-config=<config>
Provide extra config files to parse in after and in addition to the files
diff --git a/src/flake8/formatting/base.py b/src/flake8/formatting/base.py
index 2ac0ed8..e7a139a 100644
--- a/src/flake8/formatting/base.py
+++ b/src/flake8/formatting/base.py
@@ -148,7 +148,7 @@ class BaseFormatter(object):
"""Handle logic of whether to use an output file or print()."""
if self.output_fd is not None:
self.output_fd.write(output + self.newline)
- else:
+ if self.output_fd is None or self.options.tee:
print(output)
def write(self, line, source):
diff --git a/src/flake8/main/options.py b/src/flake8/main/options.py
index c725c38..a94323b 100644
--- a/src/flake8/main/options.py
+++ b/src/flake8/main/options.py
@@ -26,6 +26,7 @@ def register_default_options(option_manager):
- ``--exit-zero``
- ``-j``/``--jobs``
- ``--output-file``
+ - ``--tee``
- ``--append-config``
- ``--config``
- ``--isolated``
@@ -171,6 +172,11 @@ def register_default_options(option_manager):
help='Redirect report to a file.',
)
+ add_option(
+ '--tee', default=False, parse_from_config=True, action='store_true',
+ help='Write to stdout and output-file.',
+ )
+
# Config file options
add_option(
diff --git a/tests/unit/test_base_formatter.py b/tests/unit/test_base_formatter.py
index f148806..9da8c65 100644
--- a/tests/unit/test_base_formatter.py
+++ b/tests/unit/test_base_formatter.py
@@ -1,4 +1,5 @@
"""Tests for the BaseFormatter object."""
+import io
import optparse
import mock
@@ -11,6 +12,7 @@ from flake8.formatting import base
def options(**kwargs):
"""Create an optparse.Values instance."""
kwargs.setdefault('output_file', None)
+ kwargs.setdefault('tee', False)
return optparse.Values(kwargs)
@@ -76,15 +78,22 @@ def test_show_source_updates_physical_line_appropriately(line, column):
assert pointer.count(' ') == column
-def test_write_uses_an_output_file():
+@pytest.mark.parametrize('tee', [False, True])
+def test_write_uses_an_output_file(tee):
"""Verify that we use the output file when it's present."""
- line = 'Something to write'
- source = 'source'
+ line = u'Something to write'
+ source = u'source'
filemock = mock.Mock()
- formatter = base.BaseFormatter(options())
- formatter.output_fd = filemock
- formatter.write(line, source)
+ with mock.patch('sys.stdout', new_callable=io.StringIO) as stdout:
+ formatter = base.BaseFormatter(options(tee=tee))
+ formatter.output_fd = filemock
+ formatter.write(line, source)
+ if tee:
+ output = line + formatter.newline + source + formatter.newline
+ else:
+ output = ''
+ assert stdout.getvalue() == output
assert filemock.write.called is True
assert filemock.write.call_count == 2