Add fnmatch support to git pre-commit hook

Allows for wildcard pathname matching in ignore list.

Change-Id: I52e47c72c69e16ff9aefadfde22d1bd682df9654
Reviewed-on: https://code.wireshark.org/review/13166
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
João Valverde 2016-01-09 15:04:54 +00:00 committed by Alexis La Goutte
parent 936e4e0123
commit 0a931aa383
4 changed files with 125 additions and 37 deletions

View File

@ -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

View File

@ -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/*

101
tools/pre-commit-check.py Executable file
View File

@ -0,0 +1,101 @@
#!/bin/env python
#
# Wireshark - Network traffic analyzer
# By Gerald Combs <gerald@wireshark.org>
# 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:
#

View File

@ -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