diff --git a/git_hooks/README.rst b/git_hooks/README.rst new file mode 100644 index 00000000..6b5e7ff4 --- /dev/null +++ b/git_hooks/README.rst @@ -0,0 +1,75 @@ +Git hooks +========= + +This folder is intended to store git hooks. + +To use repository git hooks, you have two options: + +* **Change your hook path to apply all the hooks located at this folder:** + + .. code-block:: bash + + git config core.hooksPath git_hooks + + .. note:: + + ``core.hooksPath`` is added only at 2.9.0 version of git, so please update git version or use symlinks + +* **Take the specific hook and create a sym link in *githooks* to the specific hook:** + + .. code-block:: bash + + ln -s git_hooks/pre-commit .git/hooks + + +Hooks can be muted with --no-verify option: ``git commit --no-verify`` + +* ``pre-commit`` hook automatically fixes the following PEP8 rules: + + * E101 - Reindent all lines. + * E11 - Fix indentation. (not include E112 and E113) + * E121 - Fix indentation to be a multiple of four. + * E122 - Add absent indentation for hanging indentation. + * E123 - Align closing bracket to match opening bracket. + * E124 - Align closing bracket to match visual indentation. + * E125 - Indent to distinguish line from next logical line. + * E126 - Fix over-indented hanging indentation. + * E127 - Fix visual indentation. + * E128 - Fix visual indentation. + * E20 - Remove extraneous whitespace. + * E211 - Remove extraneous whitespace. + * E22 - Fix extraneous whitespace around keywords. + * E224 - Remove extraneous whitespace around operator. + * E226 - Fix missing whitespace around arithmetic operator. + * E227 - Fix missing whitespace around bitwise/shift operator. + * E228 - Fix missing whitespace around modulo operator. + * E231 - Add missing whitespace. + * E241 - Fix extraneous whitespace around keywords. + * E242 - Remove extraneous whitespace around operator. + * E251 - Remove whitespace around parameter '=' sign. + * E252 - Missing whitespace around parameter equals. + * E26 - Fix spacing after comment hash for inline comments. + * E265 - Fix spacing after comment hash for block comments. + * E27 - Fix extraneous whitespace around keywords. + * E301 - Add missing blank line. + * E302 - Add missing 2 blank lines. + * E303 - Remove extra blank lines. + * E304 - Remove blank line following function decorator. + * E306 - Expected 1 blank line before a nested definition + * E401 - Put imports on separate lines. + * E501 - Try to make lines fit within --max-line-length characters. + * E502 - Remove extraneous escape of newline. + * E701 - Put colon-separated compound statement on separate lines. + * E70 - Put semicolon-separated compound statement on separate lines. + * E721 - Use "isinstance()" instead of comparing types directly. + * E722 - Fix bare except. + * W291 - Remove trailing whitespace. + * W292 - Add a single newline at the end of the file. + * W293 - Remove trailing whitespace on blank line. + * W391 - Remove trailing blank lines. + * W601 - Use "in" rather than "has_key()". + * W602 - Fix deprecated form of raising exception. + * W603 - Use "!=" instead of "<>" + * W604 - Use "repr()" instead of backticks. + + More information can be found in the official `autopep8 repository `_ diff --git a/git_hooks/pre-commit b/git_hooks/pre-commit new file mode 100755 index 00000000..affe80e6 --- /dev/null +++ b/git_hooks/pre-commit @@ -0,0 +1,82 @@ +#!/usr/bin/env python +# Copyright (c) 2017 Ekaterina Chernova (@katyafervent) +# Copyright (c) 2016 Christian Brueffer (@cbrueffer ) +# Copyright (c) 2015 Youta EGUSA (@chibiegg) +# Copyright (c) 2010 Kevin McConnell (@lentil) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import with_statement, print_function +import os +import re +import subprocess +import sys + +# Use just one of these +select_codes = [] +ignore_codes = [] + +# Add parameters like '--max-line-length' below +overrides = ['--max-line-length=160'] + + +def system(*args, **kwargs): + kwargs.setdefault('stdout', subprocess.PIPE) + proc = subprocess.Popen(args, **kwargs) + out, err = proc.communicate() + return out + + +def autopep8(filepath): + args = ['autopep8', '--in-place', '--verbose', '--ignore-local-config'] + if select_codes and ignore_codes: + print(u'Error: select and ignore codes are mutually exclusive') + sys.exit(1) + elif select_codes: + args.extend(('--select', ','.join(select_codes))) + elif ignore_codes: + args.extend(('--ignore', ','.join(ignore_codes))) + args.extend(overrides) + args.append(filepath) + result = system(*args) + print(result) + + +def main(): + print('Executing autopep8 pre-commit hook') + try: + import autopep8 as ap8 + except ImportError: + print('"autopep8" is required. Please install with `pip install autopep8`.', file=sys.stderr) + exit(1) + + modified = re.compile('^[AM]+\s+(?P.*\.py)', re.MULTILINE) + basedir = system('git', 'rev-parse', '--show-toplevel').decode('utf-8').strip() + files = system('git', 'status', '--porcelain').decode('utf-8') + files = modified.findall(files) + + for name in files: + filepath = os.path.join(basedir, name) + autopep8(filepath) + system('git', 'add', filepath) + + +if __name__ == '__main__': + main() +