summaryrefslogtreecommitdiff
path: root/tools/infrastructure
diff options
context:
space:
mode:
authorKozoriz <kozorizandriy@gmail.com>2016-04-26 13:28:27 +0300
committerKozoriz <kozorizandriy@gmail.com>2016-04-26 15:50:21 +0300
commitc8048dd24dc40502390ad12c1a985d0b2ec7dd7f (patch)
tree4da29e0bf915dcf86f066badb75fd891c3e39eb4 /tools/infrastructure
parent4ecdb2a83871784f34430ed09d5ef6a2c0855506 (diff)
downloadsdl_core-c8048dd24dc40502390ad12c1a985d0b2ec7dd7f.tar.gz
Add infrastructure scripts
+ install precommit-hook + format code to style + utils script + file of precommit-hook
Diffstat (limited to 'tools/infrastructure')
-rw-r--r--tools/infrastructure/format_src.py37
-rw-r--r--tools/infrastructure/git-hooks/pre-commit102
-rw-r--r--tools/infrastructure/install_hooks.py40
-rw-r--r--tools/infrastructure/utils.py43
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)