2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; either version 2 of the License, or
5
# (at your option) any later version.
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
"""Flake8 type checking before commits.
18
Set the ``flake8.pre_commit_check`` configuration variable to True
23
from __future__ import absolute_import
25
from breezy.errors import BzrError, DependencyNotPresent
28
class Flake8Errors(BzrError):
31
"Running in strict flake8 mode; aborting commit, "
32
"since %(errors)d flake8 errors exist."
35
def __init__(self, errors):
39
def _delta_files(tree_delta):
40
for path, file_id, kind in tree_delta.added:
49
) in tree_delta.modified:
50
if kind == "file" and text_modified:
59
) in tree_delta.renamed:
60
if kind == "file" and text_modified:
62
for path, id, old_kind, new_kind in tree_delta.kind_changed:
63
if new_kind == "file":
67
def _copy_files_to(tree, target_dir, files):
68
from breezy import osutils
71
target_path = os.path.join(target_dir, relpath)
72
os.makedirs(os.path.dirname(target_path))
73
with tree.get_file(relpath) as inf, open(target_path, "wb") as outf:
74
osutils.pumpfile(inf, outf)
78
def _update_paths(checker_manager, temp_prefix):
79
temp_prefix_length = len(temp_prefix)
80
for checker in checker_manager.checkers:
81
filename = checker.display_name
82
if filename.startswith(temp_prefix):
83
checker.display_name = os.path.relpath(
84
filename[temp_prefix_length:]
88
def hook(config, tree_delta, future_tree):
89
"""Execute Flake8 on the files in git's index.
91
Determine which files are about to be committed and run Flake8 over
92
them to check for violations.
95
If True, return the total number of errors/violations found by
96
Flake8. This will cause the hook to fail.
98
Total number of errors found during the run.
103
from flake8.main import application
104
except ImportError as e:
105
raise DependencyNotPresent('flake8', e)
108
strict = config.get("flake8.strict")
110
app = application.Application()
111
with tempfile.TemporaryDirectory() as tempdir:
113
_copy_files_to(future_tree, tempdir, _delta_files(tree_delta))
115
app.initialize([tempdir])
116
app.options._running_from_vcs = True
117
app.run_checks(filepaths)
118
_update_paths(app.file_checker_manager, tempdir)
123
raise Flake8Errors(app.result_count)
126
def _check_flake8(local, master, old_revno, old_revid, future_revno,
127
future_revid, tree_delta, future_tree):
128
branch = local or master
129
config = branch.get_config_stack()
130
if config.get("flake8.pre_commit_check"):
131
hook(config, tree_delta, future_tree)
134
from breezy.branch import Branch
135
Branch.hooks.install_named_hook("pre_commit", _check_flake8, "Check flake8")