diff options
author | Kozoriz <kozorizandriy@gmail.com> | 2016-04-26 13:28:27 +0300 |
---|---|---|
committer | Kozoriz <kozorizandriy@gmail.com> | 2016-04-26 15:50:21 +0300 |
commit | c8048dd24dc40502390ad12c1a985d0b2ec7dd7f (patch) | |
tree | 4da29e0bf915dcf86f066badb75fd891c3e39eb4 /tools | |
parent | 4ecdb2a83871784f34430ed09d5ef6a2c0855506 (diff) | |
download | sdl_core-c8048dd24dc40502390ad12c1a985d0b2ec7dd7f.tar.gz |
Add infrastructure scripts
+ install precommit-hook
+ format code to style
+ utils script
+ file of precommit-hook
Diffstat (limited to 'tools')
-rw-r--r-- | tools/infrastructure/format_src.py | 37 | ||||
-rw-r--r-- | tools/infrastructure/git-hooks/pre-commit | 102 | ||||
-rw-r--r-- | tools/infrastructure/install_hooks.py | 40 | ||||
-rw-r--r-- | tools/infrastructure/utils.py | 43 |
4 files changed, 222 insertions, 0 deletions
diff --git a/tools/infrastructure/format_src.py b/tools/infrastructure/format_src.py new file mode 100644 index 0000000000..b7927b2708 --- /dev/null +++ b/tools/infrastructure/format_src.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Format all sources with clang-format. All *.cc and *h in the src dir +are affected. Excluded from formatting sources in the "3rd_party" and +in the "3rd_party-static" dirs. For the formatting used ".clang-format" +in the project root. +""" + +import os +from utils import setup_working_dir, walk_dir, run_cmd +import re + + +INCLUDE_PATTERNS = ['^.*\.cc$', '^.*\.h$', '^.*\.cpp$', '^.*\.hpp$'] +EXCLUDE_PATTERNS = ['^.*3rd_party.*$'] +FORMAT_CMD = 'clang-format -i -style=file {}' + + +def main(): + ''' Main logic ''' + setup_working_dir() + print 'Current working dir is {}'.format(os.getcwd()) + + def action(file_path): + if re.match('|'.join(INCLUDE_PATTERNS), file_path, re.M | re.I): + if not re.match('|'.join(EXCLUDE_PATTERNS), + file_path, + re.M | re.I): + print 'Formatting file {}'.format(file_path) + run_cmd(FORMAT_CMD.format(file_path)) + walk_dir('src', action) + + +if __name__ == '__main__': + main() diff --git a/tools/infrastructure/git-hooks/pre-commit b/tools/infrastructure/git-hooks/pre-commit new file mode 100644 index 0000000000..1819d8f3b8 --- /dev/null +++ b/tools/infrastructure/git-hooks/pre-commit @@ -0,0 +1,102 @@ +#!/bin/bash + +# Hide all unstaged changes to prevent any influence of the further checks +function POP_STASHED() { + # pop stashed changes if working directory isn't clean + if [ -n "$IS_DIRTY" ]; then + git reset --hard HEAD > /dev/null + skipped=$(git ls-files -t | grep ^S | cut -d' ' -f2-) + git stash pop --index > /dev/null + echo "$skipped" | while read file; do git update-index --skip-worktree "$file"; done + fi +} + +# determine working tree status +IS_DIRTY=`[[ $(git diff --shortstat 2> /dev/null | tail -n1) != "" ]] && echo '*'` + +# stash not staged for commit changes +if [ -n "$IS_DIRTY" ]; then + git stash save --keep-index + trap POP_STASHED EXIT +fi +# End of stashing + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +TEXT_DEFAULT="\\033[0;39m" +TEXT_INFO="\\033[1;32m" +TEXT_ERROR="\\033[1;31m" +TEXT_UNDERLINE="\\0033[4m" +TEXT_BOLD="\\0033[1m" + +# check for odd whitespace +git diff --check --cached --color +if [ "$?" -ne "0" ]; then + echo -e "$TEXT_ERROR" "Your changes introduce whitespace errors" "$TEXT_DEFAULT" + exit 1 +fi + +# Auto update c++ files with clang-format +CLANG_FORMAT=clang-format +# Verify clang-format +CLANG_FORMAT_REQUIRED_VERSION=3.6 +CLANG_FORMAT_CURRENT_VERSION=$($CLANG_FORMAT -version) +if [[ $CLANG_FORMAT_CURRENT_VERSION != *$CLANG_FORMAT_REQUIRED_VERSION* ]] +then + echo -e "$TEXT_ERROR" "Wrong version of the clang-format. Required: $CLANG_FORMAT_REQUIRED_VERSION. Got: $CLANG_FORMAT_CURRENT_VERSION" "$TEXT_DEFAULT" + exit 1 +fi + +CPP_SRC_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E "(\.cc$|\.cpp$|\.h$|\.hpp$)" | grep -v "3rd_party") +if [ -n "$CPP_SRC_FILES" ]; then + $CLANG_FORMAT -i -style=file $CPP_SRC_FILES + # Add possible changes after formating to the index + git add $CPP_SRC_FILES +fi + +# Auto-check for pep8 in python code +PYTHON_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -e '\.py$') + +if [ -n "$PYTHON_FILES" ]; then + flake8 $PYTHON_FILES + if [ "$?" -ne "0" ]; then + echo -e "$TEXT_ERROR" "Flake8 reports about the issues in the python scripts" "$TEXT_DEFAULT" + exit 2 + fi +fi
\ No newline at end of file diff --git a/tools/infrastructure/install_hooks.py b/tools/infrastructure/install_hooks.py new file mode 100644 index 0000000000..6f93e02c41 --- /dev/null +++ b/tools/infrastructure/install_hooks.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Install (copy) git hooks +""" + +import os +import glob +import shutil +from utils import setup_working_dir + + +def uninstall_hooks(hooks_dir): + print 'Deleting existing pre-commit hooks from {}'.format(hooks_dir) + files = glob.glob(os.path.join(hooks_dir, 'pre-commit*')) + for item in files: + os.remove(item) + + +def install_hooks(src_dir, dst_dir): + print 'Installing pre-commit hooks' + src_files = glob.glob(os.path.join(src_dir, 'pre-commit*')) + for item in src_files: + shutil.copy(item, dst_dir) + + +def main(): + ''' Main logic ''' + setup_working_dir() + print 'Current working dir is {}'.format(os.getcwd()) + hooks_src_dir = os.path.join( + os.getcwd(), 'tools', 'infrastructure', 'git-hooks') + hooks_dst_dir = os.path.join(os.getcwd(), '.git', 'hooks') + uninstall_hooks(hooks_dst_dir) + install_hooks(hooks_src_dir, hooks_dst_dir) + + +if __name__ == '__main__': + main() diff --git a/tools/infrastructure/utils.py b/tools/infrastructure/utils.py new file mode 100644 index 0000000000..ec1af42cce --- /dev/null +++ b/tools/infrastructure/utils.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- + +""" Misc utils used by other modules """ + +import os +import contextlib + + +def setup_working_dir(): + """ Prepare current working dir (in case if script is called from + outside). Set it to the project root. + """ + os.chdir(os.path.join(os.path.dirname( + os.path.realpath(__file__)), os.pardir, os.pardir)) + + +def run_cmd(cmd_line): + import subprocess + + return subprocess.call(cmd_line, shell=True) + + +def walk_dir(directory, action, recursive=True): + """ Walks a directory, and executes the action on each file """ + directory = os.path.abspath(directory) + for file in [file for file in os.listdir(directory) if file not in [os.curdir, os.pardir]]: + file_path = os.path.join(directory, file) + action(file_path) + if recursive and os.path.isdir(file_path): + walk_dir(file_path, action) + + +@contextlib.contextmanager +def working_directory(path): + """ A context manager which changes the working directory to the given + path, and then changes it back to it's previous value on exit. + """ + prev_cwd = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(prev_cwd) |