Skip to content

Commit

Permalink
Add: Checks for commit message and diffs
Browse files Browse the repository at this point in the history
  • Loading branch information
frosch123 committed Apr 8, 2018
1 parent 62f2137 commit 5a64e10
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
test/main
test/main.git
test/goodguy
test/badguy
2 changes: 2 additions & 0 deletions Makefile
@@ -0,0 +1,2 @@
all:
@cd test; ./test.sh
56 changes: 56 additions & 0 deletions hooks/commit-msg
@@ -0,0 +1,56 @@
#!/usr/bin/env python3

import re, sys

KEYWORDS = "(Add|Feature|Change|Remove|Codechange|Cleanup|Fix|Revert|Doc|Update|Prepare)"
ISSUE = "#\d+"
COMMIT = "[0-9a-f]{4,}"

MSG_PAT1 = re.compile(KEYWORDS + "$")
MSG_PAT2 = re.compile(KEYWORDS + " " + ISSUE + "$")
MSG_PAT3 = re.compile(KEYWORDS + " " + COMMIT + "$")
MSG_PAT4 = re.compile(COMMIT + "$")

ERROR = """
*** First line of message must match: '<keyword>( #<issue>| <commit>(, (<keyword> #<issue>|<commit>))*)?: ([<section])? <Details>'
Valid <keyword>: """+KEYWORDS+"""
Examples:
'Fix: [YAPF] Infinite loop in pathfinder.'
'Fix #5926: [YAPF] Infinite loop in pathfinder.'
'Fix 80dffae130: Warning about unsigned unary minus.
'Fix #6673, 99bb3a95b4: Store the map variety setting in the samegame.'
'Revert d9065fbfbe, Fix #5922: ClientSizeChanged is only called via WndProcGdi which already has the mutex.'
'Fix #1264, Fix #2037, Fix #2038, Fix #2110: Rewrite the autoreplace kernel.'
"""

first_line = True
for l in open(sys.argv[1]):
l = l.rstrip("\n")

# Check trailing whitespace
if l != l.rstrip():
sys.stderr.write("*** Message contains trailing whitespace: '{}'\n".format(l))
sys.exit(1)

# Check ASCII, and no control chars
if any(ord(c) < 32 or ord(c) > 127 for c in l):
sys.stderr.write("*** Message contains non-ASCII characters or tabs: '{}'\n".format(l))
sys.exit(1)

# Check first line
if first_line:
first_line = False

parts = l.split(": ", 1)
if len(parts) != 2:
sys.stderr.write(ERROR)
sys.exit(1)

prefixes = parts[0].split(", ")
first_prefix = True
for p in prefixes:
if (len(prefixes) == 1 and MSG_PAT1.match(p)) or MSG_PAT2.match(p) or MSG_PAT3.match(p) or (not first_prefix and MSG_PAT4.match(p)):
first_prefix = False
else:
sys.stderr.write(ERROR)
sys.exit(1)
49 changes: 14 additions & 35 deletions hooks/update
@@ -1,27 +1,6 @@
#!/bin/sh
#
# An example hook script to block unannotated tags from entering.
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
# Config
# ------
# hooks.allowunannotated
# This boolean sets whether unannotated tags will be allowed into the
# repository. By default they won't be.
# hooks.allowdeletetag
# This boolean sets whether deleting tags will be allowed in the
# repository. By default they won't be.
# hooks.allowmodifytag
# This boolean sets whether a tag may be modified after creation. By default
# it won't be.
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
# hooks.denycreatebranch
# This boolean sets whether remotely creating branches will be denied
# in the repository. By default this is allowed.
# Based on default update.sample hook
#

# --- Command line
Expand All @@ -43,20 +22,13 @@ if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
fi

# --- Config
allowunannotated=$(git config --bool hooks.allowunannotated)
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
denycreatebranch=$(git config --bool hooks.denycreatebranch)
allowdeletetag=$(git config --bool hooks.allowdeletetag)
allowmodifytag=$(git config --bool hooks.allowmodifytag)
allowunannotated="false"
allowdeletebranch="false"
denycreatebranch="false"
allowdeletetag="false"
allowmodifytag="false"

# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
case "$projectdesc" in
"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
;;
esac
tmp_msg="/tmp/githook_update_msg.tmp"

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
Expand Down Expand Up @@ -99,6 +71,13 @@ case "$refname","$newrev_type" in
echo "*** Creating a branch is not allowed in this repository" >&2
exit 1
fi
hashes=$(git rev-list ${oldrev}..${newrev})
for h in ${hashes}
do
git diff --check ${h}^..${h} || exit 1
git cat-file commit ${h} | sed '1,/^$/d' > ${tmp_msg}
${GIT_DIR}/hooks/commit-msg ${tmp_msg} || exit 1
done
;;
refs/heads/*,delete)
# delete branch
Expand Down
7 changes: 7 additions & 0 deletions test/cases/case1.cpp
@@ -0,0 +1,7 @@
/** Foo
* bar
*/
int foo()
{
return bar;
}
7 changes: 7 additions & 0 deletions test/cases/case2.cpp
@@ -0,0 +1,7 @@
/** Foo
* bar
*/
int foo()
{
return bar;
}
7 changes: 7 additions & 0 deletions test/cases/case3.cpp
@@ -0,0 +1,7 @@
/** Foo
* bar
*/
int foo()
{
return bar;
}
8 changes: 8 additions & 0 deletions test/cases/case4.cpp
@@ -0,0 +1,8 @@
/** Foo
* bar
*/
int foo()
{
int bar = 1;
return bar;
}
7 changes: 7 additions & 0 deletions test/cases/case5.cpp
@@ -0,0 +1,7 @@
/** Foo
* bar
*/
int foo()
{
return bar;
}
164 changes: 164 additions & 0 deletions test/test.sh
@@ -0,0 +1,164 @@
#!/bin/sh

git_good()
{
git "$@" >/dev/null 2>&1
if [ $? -ne 0 ]
then
echo "Command '$@' failed"
exit 1
fi
}

git_bad()
{
git "$@" >/dev/null 2>&1
if [ $? -eq 0 ]
then
echo "Command '$@' should have failed"
exit 1
fi
}

test_commit_good()
{
git_good commit -m "$1"
}

test_commit_bad()
{
git_bad commit -m "$1"
}

# reset all
rm -rf main main.git goodguy badguy

# setup main
git_good init main
cd main
git_good config --local core.autocrlf input
git_good config --local core.whitespace trailing-space,space-before-tab,indent-with-non-tab
echo "init" > readme
git_good add readme
test_commit_good "Add: Init"

cd ..
mv main/.git main.git
rm -rf main
git_good --git-dir=main.git config core.bare true

cd main.git/hooks
ln -s -t . ../../../hooks/*
cd ../..

# setup goodguy
echo "goodguy"
git_good clone main.git goodguy
cd goodguy
git_good config --local core.autocrlf input
git_good config --local core.whitespace trailing-space,space-before-tab,indent-with-non-tab
cd .git/hooks
ln -s -t . ../../../../hooks/*
cd ../../../

# test cases
cp cases/* goodguy
cd goodguy

git_good add case1.cpp
test_commit_bad "Add No ref"
test_commit_bad "-Add: No ref"
test_commit_bad " Add: No ref"
test_commit_bad "Add : No ref"
test_commit_bad "Add:No ref"
test_commit_good "Add: No ref"

cp case1.cpp case11.cpp
git_good add case11.cpp
test_commit_bad "Add [FS#123]: Issue ref"
test_commit_bad "Add [#123]: Issue ref"
test_commit_bad "Add, #123: Issue ref"
test_commit_bad "Add #123: Issue ref"
test_commit_bad "Add #123 : Issue ref"
test_commit_bad "Add # 123: Issue ref"
test_commit_bad "Add #123:Issue ref"
test_commit_good "Add #123: Issue ref"

cp case1.cpp case12.cpp
git_good add case12.cpp
test_commit_bad "Fix, abcdef: Commit ref"
test_commit_bad "Fix abcdef: Commit ref"
test_commit_bad "Fix abcdef : Commit ref"
test_commit_bad "Fix abcdef:Commit ref"
test_commit_good "Fix abcdef: Commit ref"

cp case1.cpp case13.cpp
git_good add case13.cpp
test_commit_bad "Fix #123 #456: Two issue ref"
test_commit_bad "Fix #123, #456: Two issue ref"
test_commit_bad "Fix #123,Fix #456: Two issue ref"
test_commit_good "Fix #123, Fix #456: Two issue ref"

cp case1.cpp case14.cpp
git_good add case14.cpp
test_commit_bad "abcdef, Fix #456: Commit and issue ref"
test_commit_bad "Fix abcdef #456: Commit and issue ref"
test_commit_bad "Fix abcdef, #456: Commit and issue ref"
test_commit_good "Fix abcdef, Fix #456: Commit and issue ref"

cp case1.cpp case15.cpp
git_good add case15.cpp
test_commit_bad "#123, Fix abcdef: Issue and commit ref"
test_commit_bad "Fix #123 abcdef: Issue and commit ref"
test_commit_bad "Fix #123,abcdef: Issue and commit ref"
test_commit_good "Fix #123, abcdef: Issue and commit ref"

cp case1.cpp case16.cpp
git_good add case16.cpp
test_commit_good "Fix #123, Fix abcdef: Issue and commit ref"

cp case1.cpp case17.cpp
git_good add case17.cpp
test_commit_bad "fedcba, Fix abcdef: Two commit ref"
test_commit_bad "Fix fedcba abcdef: Two commit ref"
test_commit_good "Fix fedcba, abcdef: Two commit ref"

cp case1.cpp case18.cpp
git_good add case18.cpp
test_commit_good "Fix fedcba, Fix abcdef: Two commit ref"

git_good add case2.cpp
test_commit_bad "Add: Whitespace"
git_good reset case2.cpp

#git_good add case3.cpp
#test_commit_bad "Add: Tabs"
#git_good reset case3.cpp

git_good add case4.cpp
test_commit_bad "Add: Mixed indent"
git_good reset case4.cpp

#git_good add case5.cpp
#test_commit_bad "Add: Space indent"
#git_good reset case5.cpp

git_good push

# setup badguy
cd ..
echo "badguy"
git_good clone main.git badguy
cd badguy

cp case1.cpp case19.cpp
git_good add case19.cpp
test_commit_good "fixit"
git_bad push

cp ../cases/case2.cpp .
git_good add case2.cpp
git_good commit --amend -m "Fix: Message"
git_bad push

cd ..

0 comments on commit 5a64e10

Please sign in to comment.