diff options
Diffstat (limited to 'scripts/commitcheck.sh')
| -rwxr-xr-x | scripts/commitcheck.sh | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/scripts/commitcheck.sh b/scripts/commitcheck.sh new file mode 100755 index 000000000000..c7515c23e1d0 --- /dev/null +++ b/scripts/commitcheck.sh @@ -0,0 +1,218 @@ +#!/usr/bin/env bash + +REF="HEAD" + +# test a url +function test_url() +{ + url="$1" + if ! curl --output /dev/null --max-time 60 \ + --silent --head --fail "$url" ; then + echo "\"$url\" is unreachable" + return 1 + fi + + return 0 +} + +# test commit body for length +# lines containing urls are exempt for the length limit. +function test_commit_bodylength() +{ + length="72" + body=$(git log -n 1 --pretty=%b "$REF" | grep -Ev "http(s)*://" | grep -E -m 1 ".{$((length + 1))}") + if [ -n "$body" ]; then + echo "error: commit message body contains line over ${length} characters" + return 1 + fi + + return 0 +} + +# check for a tagged line +function check_tagged_line() +{ + regex='^\s*'"$1"':\s[[:print:]]+\s<[[:graph:]]+>$' + foundline=$(git log -n 1 "$REF" | grep -E -m 1 "$regex") + if [ -z "$foundline" ]; then + echo "error: missing \"$1\"" + return 1 + fi + + return 0 +} + +# check for a tagged line and check that the link is valid +function check_tagged_line_with_url() +{ + regex='^\s*'"$1"':\s\K([[:graph:]]+)$' + foundline=$(git log -n 1 "$REF" | grep -Po "$regex") + if [ -z "$foundline" ]; then + echo "error: missing \"$1\"" + return 1 + fi + + OLDIFS=$IFS + IFS=$'\n' + for url in $(echo -e "$foundline"); do + if ! test_url "$url"; then + return 1 + fi + done + IFS=$OLDIFS + + return 0 +} + +# check commit message for a normal commit +function new_change_commit() +{ + error=0 + + # subject is not longer than 72 characters + long_subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '.{73}') + if [ -n "$long_subject" ]; then + echo "error: commit subject over 72 characters" + error=1 + fi + + # need a signed off by + if ! check_tagged_line "Signed-off-by" ; then + error=1 + fi + + # ensure that no lines in the body of the commit are over 72 characters + if ! test_commit_bodylength ; then + error=1 + fi + + return $error +} + +function is_openzfs_port() +{ + # subject starts with OpenZFS means it's an openzfs port + subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^OpenZFS') + if [ -n "$subject" ]; then + return 0 + fi + + return 1 +} + +function openzfs_port_commit() +{ + error=0 + + # subject starts with OpenZFS dddd + subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^OpenZFS [[:digit:]]+(, [[:digit:]]+)* - ') + if [ -z "$subject" ]; then + echo "error: OpenZFS patch ports must have a subject line that starts with \"OpenZFS dddd - \"" + error=1 + fi + + # need an authored by line + if ! check_tagged_line "Authored by" ; then + error=1 + fi + + # need a reviewed by line + if ! check_tagged_line "Reviewed by" ; then + error=1 + fi + + # need ported by line + if ! check_tagged_line "Ported-by" ; then + error=1 + fi + + # need a url to openzfs commit and it should be valid + if ! check_tagged_line_with_url "OpenZFS-commit" ; then + error=1 + fi + + # need a url to illumos issue and it should be valid + if ! check_tagged_line_with_url "OpenZFS-issue" ; then + error=1 + fi + + return $error +} + +function is_coverity_fix() +{ + # subject starts with Fix coverity defects means it's a coverity fix + subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^Fix coverity defects') + if [ -n "$subject" ]; then + return 0 + fi + + return 1 +} + +function coverity_fix_commit() +{ + error=0 + + # subject starts with Fix coverity defects: CID dddd, dddd... + subject=$(git log -n 1 --pretty=%s "$REF" | + grep -E -m 1 'Fix coverity defects: CID [[:digit:]]+(, [[:digit:]]+)*') + if [ -z "$subject" ]; then + echo "error: Coverity defect fixes must have a subject line that starts with \"Fix coverity defects: CID dddd\"" + error=1 + fi + + # need a signed off by + if ! check_tagged_line "Signed-off-by" ; then + error=1 + fi + + # test each summary line for the proper format + OLDIFS=$IFS + IFS=$'\n' + for line in $(git log -n 1 --pretty=%b "$REF" | grep -E '^CID'); do + echo "$line" | grep -E '^CID [[:digit:]]+: ([[:graph:]]+|[[:space:]])+ \(([[:upper:]]|\_)+\)' > /dev/null + # shellcheck disable=SC2181 + if [[ $? -ne 0 ]]; then + echo "error: commit message has an improperly formatted CID defect line" + error=1 + fi + done + IFS=$OLDIFS + + # ensure that no lines in the body of the commit are over 72 characters + if ! test_commit_bodylength; then + error=1 + fi + + return $error +} + +if [ -n "$1" ]; then + REF="$1" +fi + +# if openzfs port, test against that +if is_openzfs_port; then + if ! openzfs_port_commit ; then + exit 1 + else + exit 0 + fi +fi + +# if coverity fix, test against that +if is_coverity_fix; then + if ! coverity_fix_commit; then + exit 1 + else + exit 0 + fi +fi + +# have a normal commit +if ! new_change_commit ; then + exit 1 +fi + +exit 0 |
