summaryrefslogtreecommitdiff
path: root/src/flake8
diff options
context:
space:
mode:
authorIan Cordasco <graffatcolmingov@gmail.com>2016-08-06 14:16:08 -0500
committerIan Cordasco <graffatcolmingov@gmail.com>2016-08-07 12:31:14 -0500
commitf67f481beea1f32e503d346e9d4d3f2f2a8b2ebe (patch)
treea147072597dfff8d3df7333a744573f29ef95fee /src/flake8
parentf768ed6fd0101de656e19d3029952e69a437549e (diff)
downloadflake8-f67f481beea1f32e503d346e9d4d3f2f2a8b2ebe.tar.gz
Add --bug-report flag to help bug reporters
When invoked it will print out JSON that has all of the debugging information needed by the maintainers to diagnose or reproduce a bug. Closes #207
Diffstat (limited to 'src/flake8')
-rw-r--r--src/flake8/main/debug.py62
-rw-r--r--src/flake8/main/options.py11
-rw-r--r--src/flake8/options/manager.py5
3 files changed, 76 insertions, 2 deletions
diff --git a/src/flake8/main/debug.py b/src/flake8/main/debug.py
new file mode 100644
index 0000000..e6ea141
--- /dev/null
+++ b/src/flake8/main/debug.py
@@ -0,0 +1,62 @@
+"""Module containing the logic for our debugging logic."""
+from __future__ import print_function
+
+import json
+import platform
+
+import setuptools
+
+
+def print_information(option, option_string, value, parser,
+ option_manager=None):
+ """Print debugging information used in bug reports.
+
+ :param option:
+ The optparse Option instance.
+ :type option:
+ optparse.Option
+ :param str option_string:
+ The option name
+ :param value:
+ The value passed to the callback parsed from the command-line
+ :param parser:
+ The optparse OptionParser instance
+ :type parser:
+ optparse.OptionParser
+ :param option_manager:
+ The Flake8 OptionManager instance.
+ :type option_manager:
+ flake8.options.manager.OptionManager
+ """
+ if not option_manager.registered_plugins:
+ # NOTE(sigmavirus24): Flake8 parses options twice. The first time, we
+ # will not have any registered plugins. We can skip this one and only
+ # take action on the second time we're called.
+ return
+ print(json.dumps(information(option_manager), indent=2, sort_keys=True))
+ raise SystemExit(False)
+
+
+def information(option_manager):
+ """Generate the information to be printed for the bug report."""
+ return {
+ 'version': option_manager.version,
+ 'plugins': plugins_from(option_manager),
+ 'dependencies': dependencies(),
+ 'platform': {
+ 'python_implementation': platform.python_implementation(),
+ 'python_version': platform.python_version(),
+ 'system': platform.system(),
+ },
+ }
+
+
+def plugins_from(option_manager):
+ """Generate the list of plugins installed."""
+ return [{'plugin': plugin, 'version': version}
+ for (plugin, version) in sorted(option_manager.registered_plugins)]
+
+
+def dependencies():
+ """Generate the list of dependencies we care about."""
+ return [{'dependency': 'setuptools', 'version': setuptools.__version__}]
diff --git a/src/flake8/main/options.py b/src/flake8/main/options.py
index c725c38..47fb30c 100644
--- a/src/flake8/main/options.py
+++ b/src/flake8/main/options.py
@@ -1,5 +1,6 @@
"""Contains the logic for all of the default options for Flake8."""
from flake8 import defaults
+from flake8.main import debug
from flake8.main import vcs
@@ -29,6 +30,8 @@ def register_default_options(option_manager):
- ``--append-config``
- ``--config``
- ``--isolated``
+ - ``--benchmark``
+ - ``--bug-report``
"""
add_option = option_manager.add_option
@@ -199,3 +202,11 @@ def register_default_options(option_manager):
'--benchmark', default=False, action='store_true',
help='Print benchmark information about this run of Flake8',
)
+
+ # Debugging
+
+ add_option(
+ '--bug-report', action='callback', callback=debug.print_information,
+ callback_kwargs={'option_manager': option_manager},
+ help='Print information necessary when preparing a bug report',
+ )
diff --git a/src/flake8/options/manager.py b/src/flake8/options/manager.py
index de9356e..b536907 100644
--- a/src/flake8/options/manager.py
+++ b/src/flake8/options/manager.py
@@ -240,9 +240,10 @@ class OptionManager(object):
LOG.debug('Extending default select list with %r', error_codes)
self.extended_default_select.update(error_codes)
- def generate_versions(self, format_str='%(name)s: %(version)s'):
+ def generate_versions(self, format_str='%(name)s: %(version)s',
+ join_on=', '):
"""Generate a comma-separated list of versions of plugins."""
- return ', '.join(
+ return join_on.join(
format_str % self.format_plugin(plugin)
for plugin in self.registered_plugins
)