From 8fbc08d119b8fb0c15f392fdfc67e16e22a2a2c9 Mon Sep 17 00:00:00 2001 From: coagulant Date: Tue, 19 Nov 2013 22:57:19 +0400 Subject: [PATCH] Add flake8 support Flake8 is PEP8 + PyFlakes + Cyclomatic complexity check --- discover_jenkins/tasks/run_flake8.py | 57 ++++++++++++++++++++++++++++ docs/tasks.rst | 7 ++++ tests/requirements.pip | 1 + tests/test_project/settings.py | 3 +- tests/tests/test_runner.py | 3 +- 5 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 discover_jenkins/tasks/run_flake8.py diff --git a/discover_jenkins/tasks/run_flake8.py b/discover_jenkins/tasks/run_flake8.py new file mode 100644 index 0000000..148dffa --- /dev/null +++ b/discover_jenkins/tasks/run_flake8.py @@ -0,0 +1,57 @@ +# coding: utf-8 +import os +import sys +import pep8 +from flake8.engine import get_style_guide +from optparse import make_option +from discover_jenkins.tasks.run_pep8 import Pep8Task +from discover_jenkins.utils import get_app_locations + + +class Flake8Task(Pep8Task): + option_list = Pep8Task.option_list + (make_option( + '--max-complexity', + dest='max_complexity', + help='McCabe complexity treshold'),) + + def __init__(self, **options): + super(Flake8Task, self).__init__(**options) + + if options.get('flake8_file_output', True): + output_dir = options['output_dir'] + if not os.path.exists(output_dir): + os.makedirs(output_dir) + self.output = open(os.path.join(output_dir, 'flake8.report'), 'w') + else: + self.output = sys.stdout + + if options['max_complexity']: + self.pep8_options['max_complexity'] = int(options['max_complexity']) + + def teardown_test_environment(self, **kwargs): + class JenkinsReport(pep8.BaseReport): + def error(instance, line_number, offset, text, check): + code = super(JenkinsReport, instance).error( + line_number, offset, text, check, + ) + + if not code: + return + sourceline = instance.line_offset + line_number + self.output.write( + '%s:%s:%s: %s\n' % + (instance.filename, sourceline, offset + 1, text), + ) + + flake8style = get_style_guide( + parse_argv=False, + config_file=self.pep8_rcfile, + reporter=JenkinsReport, + **self.pep8_options) + + # Jenkins pep8 validator requires relative paths + project_root = os.path.abspath(os.path.dirname(__name__)) + for location in map(lambda x: os.path.relpath(x, project_root), get_app_locations()): + flake8style.input_dir(location) + + self.output.close() diff --git a/docs/tasks.rst b/docs/tasks.rst index d74bc1f..0a681fd 100644 --- a/docs/tasks.rst +++ b/docs/tasks.rst @@ -128,3 +128,10 @@ Pep8Task ``discover_jenkins.tasks.run_pep8.Pep8Task`` Run pep8 across your apps. Uses the ``TEST_PROJECT_APPS`` setting. + +Flake8Task +========== + +``discover_jenkins.tasks.run_flake8.Flake8Task`` + +Run flake8 across your apps. Uses the ``TEST_PROJECT_APPS`` setting. diff --git a/tests/requirements.pip b/tests/requirements.pip index 69b4957..9b6445a 100644 --- a/tests/requirements.pip +++ b/tests/requirements.pip @@ -3,3 +3,4 @@ pylint>=0.23 coverage>=3.4 mock>=1.0.1 django-discover-runner>=1.0 +flake8>=2.1.0 diff --git a/tests/test_project/settings.py b/tests/test_project/settings.py index fc7d90a..0640a4e 100644 --- a/tests/test_project/settings.py +++ b/tests/test_project/settings.py @@ -32,6 +32,7 @@ TEST_RUNNER = 'discover_jenkins.runner.DiscoverCIRunner' TEST_TASKS = ( 'discover_jenkins.tasks.with_coverage.CoverageTask', 'discover_jenkins.tasks.run_pylint.PyLintTask', + 'discover_jenkins.tasks.run_flake8.Flake8Task', 'discover_jenkins.tasks.run_jshint.JSHintTask', 'discover_jenkins.tasks.run_sloccount.SlocCountTask', ) @@ -58,4 +59,4 @@ LOGGING = { 'propagate': True, }, } -} \ No newline at end of file +} diff --git a/tests/tests/test_runner.py b/tests/tests/test_runner.py index b6e0346..51762df 100644 --- a/tests/tests/test_runner.py +++ b/tests/tests/test_runner.py @@ -33,6 +33,7 @@ class TestCIRunner(TestCase): self.assertEqual(runner.get_tasks(), [tasks.with_coverage.CoverageTask, tasks.run_pylint.PyLintTask, + tasks.run_flake8.Flake8Task, tasks.run_jshint.JSHintTask, tasks.run_sloccount.SlocCountTask]) @@ -41,7 +42,7 @@ class TestCIRunner(TestCase): For now, just do a simple test to make sure the right number of options are gleaned from the tasks. """ - self.assertEqual(len(runner.get_task_options()), 14) + self.assertEqual(len(runner.get_task_options()), 20) def test_setup_test_environment(self): """