From 0a931aa383526a3481ad6a44545f7b9f723032b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Sat, 9 Jan 2016 15:04:54 +0000 Subject: [PATCH] Add fnmatch support to git pre-commit hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows for wildcard pathname matching in ignore list. Change-Id: I52e47c72c69e16ff9aefadfde22d1bd682df9654 Reviewed-on: https://code.wireshark.org/review/13166 Petri-Dish: João Valverde Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte --- tools/pre-commit | 36 ++++------- tools/pre-commit-check.conf | 13 ++++ tools/pre-commit-check.py | 101 +++++++++++++++++++++++++++++++ tools/pre-commit-checkignore.txt | 12 ---- 4 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 tools/pre-commit-check.conf create mode 100755 tools/pre-commit-check.py delete mode 100644 tools/pre-commit-checkignore.txt diff --git a/tools/pre-commit b/tools/pre-commit index bfc8aedeaa..796eb5e4ee 100755 --- a/tools/pre-commit +++ b/tools/pre-commit @@ -16,20 +16,19 @@ # http://mark-story.com/posts/view/using-git-commit-hooks-to-prevent-stupid-mistakes # -unset GREP_OPTIONS - # If the commit identifier is not given, use HEAD instead. COMMIT_ID="${1:-HEAD}" + # Path to hook script in the .git directory hook_script=${GIT_DIR:-.git}/hooks/pre-commit +# Path to check script in the tools directory +check_script=./tools/pre-commit-check.py + # Always start in the root directory of the source tree, this allows for # invocations via relative paths (such as ../tools/pre-commit): cd "$(git rev-parse --show-toplevel)" -# Path to excluded files listing -excludes=./tools/pre-commit-checkignore.txt - # Check for newer (actually, different) versions of the pre-commit script # (but only if invoked as hook, i.e. the commit ID is not given as argument). if [ -z "$1" ] && ! cmp -s "$hook_script" tools/pre-commit; then @@ -38,26 +37,13 @@ fi exit_status=0 -for FILE in `git diff-index --cached --name-status ${COMMIT_ID} | grep -v "^D" | cut -f2 | grep "\.[ch]$" | grep -v "extcap/"` ; do - - #Skip if listed - if [ -e $excludes ] && grep -Fxq "$FILE" "$excludes"; then - continue - fi - - #Check if checkhf is good - ./tools/checkhf.pl $FILE || exit_status=1 - - #Check if checkAPIs is good - ./tools/checkAPIs.pl -p $FILE || exit_status=1 - - #Check if fix-encoding-args is good - ./tools/fix-encoding-args.pl $FILE || exit_status=1 - - #Check if checkfiltername is good - ./tools/checkfiltername.pl $FILE || exit_status=1 - -done +if [ -e "$check_script" ] +then + python "$check_script" ${COMMIT_ID} || exit_status=1 +else + echo "File '$check_script' not found. Aborting." + exit 1 +fi # If there are whitespace errors, print the offending file names and fail. (from git pre-commit.sample) git diff-index --check --cached ${COMMIT_ID} || exit_status=1 diff --git a/tools/pre-commit-check.conf b/tools/pre-commit-check.conf new file mode 100644 index 0000000000..2c172d64d4 --- /dev/null +++ b/tools/pre-commit-check.conf @@ -0,0 +1,13 @@ +# Files listed here are ignored by the git pre-commit hook for the purpose +# of checking for forbidden APIs and other dissector-specific glitches. +# +# Each line is compared against the output of 'git diff-index --name-only'. +# For example to skip checking this file add: +# +# tools/pre-commit-check.conf +# +# The pathname wildcards allowed are: '*', '?', character set '[abc]' or +# negated with '[!abc]'. + +extcap/* +tools/lemon/* diff --git a/tools/pre-commit-check.py b/tools/pre-commit-check.py new file mode 100755 index 0000000000..fa66e1b439 --- /dev/null +++ b/tools/pre-commit-check.py @@ -0,0 +1,101 @@ +#!/bin/env python +# +# Wireshark - Network traffic analyzer +# By Gerald Combs +# Copyright 1998 Gerald Combs +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +import sys +import os +import re +import fnmatch +import filecmp + +TOOLS_DIR = "tools" +CHECK_CONF = "pre-commit-check.conf" + +CHECK_LIST = ["checkhf.pl", "checkAPIs.pl -p", "fix-encoding-args.pl", "checkfiltername.pl"] + +if len(sys.argv) > 2: + print("Usage: {0} [COMMIT]".format(sys.argv[0])) + sys.exit(1) + +# If the commit identifier is not given, use HEAD instead. +if len(sys.argv) == 2: + COMMIT_ID = sys.argv[1] +else: + COMMIT_ID = "HEAD" + +# Function to load our patterns from 'path' for modified files +# to be ignored (skipping any comments) +def load_checkignore(path): + try: + with open(path) as f: + patterns = f.read() + except OSError as err: + print("'" + path + "':", str(err)) + return [] + ign = [l.strip() for l in patterns.splitlines()] + ign = [l for l in ign if l and not l.startswith("#")] + return ign + +IGNORE_LIST = load_checkignore(os.path.join(TOOLS_DIR, CHECK_CONF)) + +# Run git-diff index and process/filter output +def run_diff_index(): + ret = [] + with os.popen("git diff-index --cached --name-status " + COMMIT_ID) as p: + diff = p.read() + for l in diff.splitlines(): + l = l.lstrip() + if l.startswith("D"): + continue + l = l.split() + f = l[1].strip() + if not re.search("\.[ch]$", f): + continue + for pattern in IGNORE_LIST: + if fnmatch.fnmatchcase(f, pattern): + f = None + break + if f: + ret.append(f) + return ret + +exit_status = 0 + +# For each valid modified file run our checks +for f in run_diff_index(): + for c in CHECK_LIST: + script = os.path.join(TOOLS_DIR, c) + cmd = "perl {0} {1}".format(script, f) + ret = os.system(cmd) + if ret != 0: + exit_status = 1 + +sys.exit(exit_status) + +# +# Editor modelines +# +# Local Variables: +# c-basic-offset: 4 +# indent-tabs-mode: nil +# End: +# +# ex: set shiftwidth=4 expandtab: +# :indentSize=4:noTabs=true: +# diff --git a/tools/pre-commit-checkignore.txt b/tools/pre-commit-checkignore.txt deleted file mode 100644 index 7b06998a70..0000000000 --- a/tools/pre-commit-checkignore.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Files listed here are ignored by the git pre-commit hook for the -# purpose of checking for forbidden APIs and other dissector-specific -# glitches. -# -# Each line must match a single file using the full path, exactly as -# return by 'git diff-index --name-only', e.g.: -# -#tools/pre-commit-checkignore.txt -# - -tools/lemon/lemon.c -tools/lemon/lempar.c