Add flake8 plugin for Breezy.

This commit is contained in:
Jelmer Vernooij 2019-01-08 01:33:30 +00:00
parent 0f3f4ff9b4
commit 53cae80f8a
No known key found for this signature in database
GPG key ID: 579C160D4C9E23E8
3 changed files with 152 additions and 1 deletions

View file

@ -127,6 +127,9 @@ setuptools.setup(
'quiet-filename = flake8.formatting.default:FilenameOnly', 'quiet-filename = flake8.formatting.default:FilenameOnly',
'quiet-nothing = flake8.formatting.default:Nothing', 'quiet-nothing = flake8.formatting.default:Nothing',
], ],
'breezy.plugin': [
'flake8 = flake8.main.breezy',
],
}, },
classifiers=[ classifiers=[
"Development Status :: 5 - Production/Stable", "Development Status :: 5 - Production/Stable",

145
src/flake8/main/breezy.py Normal file
View file

@ -0,0 +1,145 @@
"""Module containing the Breezy hook interface and helpers.
.. autofunction:: install
"""
from __future__ import absolute_import
__all__ = ("install")
import os
def install():
"""Install the Breezy hook script.
This searches for the ``.bzr`` directory and will install an executable
pre-commit python script in the hooks sub-directory if one does not
already exist.
It will also print a message to stdout about how to configure the hook.
:returns:
True if successful, False if the Breezy directory doesn't exist.
:rtype:
bool
"""
import breezy.bzr # noqa: F401
from breezy.branch import Branch
from breezy.errors import NotBranchError
try:
branch, _ = Branch.open_containing('.')
except NotBranchError:
return False
config = branch.get_config_stack()
config.set('flake8.pre_commit_check', True)
print("Breezy pre-commit hook installed, for configuration options see")
print("http://flake8.pycqa.org/en/latest/user/using-hooks.html")
return True
def _delta_files(tree_delta):
for path, file_id, kind in tree_delta.added:
if kind == 'file':
yield path
for (path, file_id, kind, text_modified,
meta_modified) in tree_delta.modified:
if kind == 'file' and text_modified:
yield path
for (oldpath, newpath, id, kind, text_modified,
meta_modified) in tree_delta.renamed:
if kind == 'file' and text_modified:
yield newpath
for path, id, old_kind, new_kind in tree_delta.kind_changed:
if new_kind == 'file':
yield path
def _copy_files_to(tree, target_dir, files):
from breezy import osutils
for relpath in files:
target_path = os.path.join(target_dir, relpath)
os.makedirs(os.path.dirname(target_path))
with tree.get_file(relpath) as inf, \
open(target_path, 'wb') as outf:
osutils.pumpfile(inf, outf)
yield target_path
def _update_paths(checker_manager, temp_prefix):
temp_prefix_length = len(temp_prefix)
for checker in checker_manager.checkers:
filename = checker.display_name
if filename.startswith(temp_prefix):
checker.display_name = os.path.relpath(
filename[temp_prefix_length:])
def hook(config, tree_delta, future_tree):
"""Execute Flake8 on the files in git's index.
Determine which files are about to be committed and run Flake8 over
them to check for violations.
:param bool strict:
If True, return the total number of errors/violations found by
Flake8. This will cause the hook to fail.
:returns:
Total number of errors found during the run.
:rtype:
int
"""
from flake8.main import application
import tempfile
strict = config.get('flake8.strict')
app = application.Application()
with tempfile.TemporaryDirectory() as tempdir:
filepaths = list(_copy_files_to(
future_tree, tempdir, _delta_files(tree_delta)))
app.initialize([tempdir])
app.options._running_from_vcs = True
app.run_checks(filepaths)
_update_paths(app.file_checker_manager, tempdir)
app.report_errors()
from breezy.errors import BzrError
class Flake8Errors(BzrError):
_fmt = ("Running in strict flake8 mode; aborting commit, "
"since %(errors)d flake8 errors exist.")
def __init__(self, errors):
self.errors = errors
if strict:
if app.result_count:
raise Flake8Errors(app.result_count)
def _check_flake8(local, master, old_revno, old_revid, future_revno,
future_revid, tree_delta, future_tree):
branch = local or master
config = branch.get_config_stack()
if config.get('flake8.pre_commit_check'):
hook(config, tree_delta, future_tree)
if __name__ == 'breezy.plugins.flake8':
__doc__ = """Flake8 type checking before commits.
Set the ``flake8.pre_commit_check`` configuration variable to True
to enable this.
"""
from breezy.branch import Branch
Branch.hooks.install_named_hook(
'pre_commit', _check_flake8, 'Check flake8')

View file

@ -1,5 +1,6 @@
"""Module containing some of the logic for our VCS installation logic.""" """Module containing some of the logic for our VCS installation logic."""
from flake8 import exceptions as exc from flake8 import exceptions as exc
from flake8.main import breezy
from flake8.main import git from flake8.main import git
from flake8.main import mercurial from flake8.main import mercurial
@ -8,7 +9,9 @@ from flake8.main import mercurial
# as plugins, e.g., adding a flake8.vcs entry-point. In that case, this # as plugins, e.g., adding a flake8.vcs entry-point. In that case, this
# dictionary should disappear, and this module might contain more code for # dictionary should disappear, and this module might contain more code for
# managing those bits (in conjuntion with flake8.plugins.manager). # managing those bits (in conjuntion with flake8.plugins.manager).
_INSTALLERS = {"git": git.install, "mercurial": mercurial.install} _INSTALLERS = {"git": git.install,
"mercurial": mercurial.install,
"breezy": breezy.install}
def install(option, option_string, value, parser): def install(option, option_string, value, parser):