Bug 1277851 - [mozlint] Run flake8 directories that contain a .flake8 file separately, r?AutomatedTester draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Fri, 03 Jun 2016 10:39:32 -0400
changeset 375147 f4b71266eaf23f26c02120f939f3977f1f7b10ae
parent 375132 1330c510901a9c6b574532af366f0e9acb8beb8c
child 522770 e533c2a381fa674e75a48221d456582f5094c6f8
push id20173
push userahalberstadt@mozilla.com
push dateFri, 03 Jun 2016 14:40:03 +0000
reviewersAutomatedTester
bugs1277851
milestone49.0a1
Bug 1277851 - [mozlint] Run flake8 directories that contain a .flake8 file separately, r?AutomatedTester This is a crude workaround to get subdirectory .flake8 files working. Hopefully this is temporary until flake8 3.0 is released with support for multiple config files. Note that .flake8 files that live outside of a directory that is explicitly listed in the 'include' directive, will not be considered. MozReview-Commit-ID: GtpUZHJKq52
tools/lint/docs/linters/flake8.rst
tools/lint/flake8.lint
--- a/tools/lint/docs/linters/flake8.rst
+++ b/tools/lint/docs/linters/flake8.rst
@@ -30,15 +30,21 @@ in a source directory, it must be added 
 If you wish to exclude a subdirectory of an included one, you can add it to the ``exclude``
 directive.
 
 The default configuration file lives in ``topsrcdir/.flake8``. The default configuration can be
 overriden for a given subdirectory by creating a new ``.flake8`` file in the subdirectory. Be warned
 that ``.flake8`` files cannot inherit from one another, so all configuration you wish to keep must
 be re-defined.
 
+.. warning::
+
+    Only ``.flake8`` files that live in a directory that is explicitly included in the ``include``
+    directive will be considered. See `bug 1277851`_ for more details.
+
 For an overview of the supported configuration, see `flake8's documentation`_.
 
 .. _Flake8: https://flake8.readthedocs.io/en/latest/
 .. _pep8: http://pep8.readthedocs.io/en/latest/
 .. _pyflakes: https://github.com/pyflakes/pyflakes
 .. _mccabe: https://github.com/pycqa/mccabe
+.. _bug 1277851: https://bugzilla.mozilla.org/show_bug.cgi?id=1277851
 .. _flake8's documentation: https://flake8.readthedocs.io/en/latest/config.html
--- a/tools/lint/flake8.lint
+++ b/tools/lint/flake8.lint
@@ -59,16 +59,31 @@ def process_line(line):
             res['level'] = 'warning'
 
         if res['code'] in LINE_OFFSETS:
             res['lineoffset'] = LINE_OFFSETS[res['code']]
 
     results.append(result.from_linter(LINTER, **res))
 
 
+def run_process(cmdargs):
+    # flake8 seems to handle SIGINT poorly. Handle it here instead
+    # so we can kill the process without a cryptic traceback.
+    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
+    proc = ProcessHandler(cmdargs, env=os.environ,
+                          processOutputLine=process_line)
+    proc.run()
+    signal.signal(signal.SIGINT, orig)
+
+    try:
+        proc.wait()
+    except KeyboardInterrupt:
+        proc.kill()
+
+
 def lint(files, **lintargs):
     binary = os.environ.get('FLAKE8')
     if not binary:
         try:
             binary = which.which('flake8')
         except which.WhichError:
             pass
 
@@ -81,30 +96,29 @@ def lint(files, **lintargs):
         '--format', '{"path":"%(path)s","lineno":%(row)s,'
                     '"column":%(col)s,"rule":"%(code)s","message":"%(text)s"}',
     ]
 
     exclude = lintargs.get('exclude')
     if exclude:
         cmdargs += ['--exclude', ','.join(lintargs['exclude'])]
 
-    cmdargs += files
+    # Run any paths with a .flake8 file in the directory separately so
+    # it gets picked up. This means only .flake8 files that live in
+    # directories that are explicitly included will be considered.
+    # See bug 1277851
+    no_config = []
+    for f in files:
+        if not os.path.isfile(os.path.join(f, '.flake8')):
+            no_config.append(f)
+            continue
+        run_process(cmdargs+[f])
 
-    # flake8 seems to handle SIGINT poorly. Handle it here instead
-    # so we can kill the process without a cryptic traceback.
-    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
-    proc = ProcessHandler(cmdargs, env=os.environ,
-                          processOutputLine=process_line)
-    proc.run()
-    signal.signal(signal.SIGINT, orig)
-
-    try:
-        proc.wait()
-    except KeyboardInterrupt:
-        proc.kill()
+    if no_config:
+        run_process(cmdargs+no_config)
 
     return results
 
 
 LINTER = {
     'name': "flake8",
     'description': "Python linter",
     'include': [