Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 44 additions & 28 deletions scripts/commit-msg.hook
Original file line number Diff line number Diff line change
Expand Up @@ -249,53 +249,69 @@ validate_commit_message() {
# 6. Wrap the body at 72 characters
# ------------------------------------------------------------------------------

URL_REGEX='^[[:blank:]]*(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]'

# Ensure the commit message lines are loaded into an array.
readarray -t COMMIT_MSG_LINES < "$COMMIT_MSG_FILE"

for i in "${!COMMIT_MSG_LINES[@]}"; do
LINE="${COMMIT_MSG_LINES[$i]}"
# Trim leading and trailing whitespace.
TRIMMED_LINE="${LINE#"${LINE%%[![:space:]]*}"}"
TRIMMED_LINE="${TRIMMED_LINE%"${TRIMMED_LINE##*[![:space:]]}"}"
LINE_NUMBER=$((i+1))
if [ "${#TRIMMED_LINE}" -gt 72 ] && ! [[ "$TRIMMED_LINE" =~ $URL_REGEX ]]; then
add_warning "$LINE_NUMBER" "Wrap the body at 72 characters (${#TRIMMED_LINE} chars)"
fi
done
URL_REGEX='^[[:blank:]]*(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]*[-A-Za-z0-9+&@#/%=~_|]'

# Ensure the commit message lines are loaded into an array.
readarray -t COMMIT_MSG_LINES < "$COMMIT_MSG_FILE"

for i in "${!COMMIT_MSG_LINES[@]}"; do
LINE="${COMMIT_MSG_LINES[$i]}"
# Trim leading and trailing whitespace.
TRIMMED_LINE="${LINE#"${LINE%%[![:space:]]*}"}"
TRIMMED_LINE="${TRIMMED_LINE%"${TRIMMED_LINE##*[![:space:]]}"}"
LINE_NUMBER=$((i+1))
if [ "${#TRIMMED_LINE}" -gt 72 ] && ! [[ "$TRIMMED_LINE" =~ $URL_REGEX ]]; then
add_warning "$LINE_NUMBER" "Wrap the body at 72 characters (${#TRIMMED_LINE} chars)"
fi
done

# 7. Use the body to explain what and why vs. how
# 7. Ensure the commit subject has more than one word.
# ------------------------------------------------------------------------------

# 8. Do no write single worded commits
if [ "$(echo "${COMMIT_SUBJECT_TO_PROCESS}" | wc -w)" -le 1 ]; then
add_warning 1 "Do not write single-word commits. Provide a descriptive subject"
fi

# 7a. Avoid using C source filenames as the commit subject.
if [[ "${COMMIT_SUBJECT_TO_PROCESS}" =~ ^[_a-zA-Z0-9]+\.[ch]$ ]]; then
add_warning 1 "Avoid mentioning C source filenames in the commit subject"
fi

# 11a. Disallow parentheses in the commit subject.
if [[ ${COMMIT_SUBJECT_TO_PROCESS} =~ [\(\)] ]]; then
add_warning 1 "Avoid using parentheses '()' in commit subjects"
fi

# 8. Use the body to explain what and why vs. how
# ------------------------------------------------------------------------------

COMMIT_SUBJECT_WORDS=(${COMMIT_SUBJECT_TO_PROCESS})
test "${#COMMIT_SUBJECT_WORDS[@]}" -gt 1
test $? -eq 0 || add_warning 1 "Do no write single worded commits"
# Count non-comment, non-blank lines excluding "Change-Id:".
NON_COMMENT_COUNT=$(sed '/^[[:space:]]*#/d;/^[[:space:]]*$/d;/^[[:space:]]*Change-Id:/d' "${COMMIT_MSG_FILE}" | wc -l | xargs)

# 8a. Do not mention C source filenames
[[ ${COMMIT_SUBJECT_TO_PROCESS} =~ [_a-zA-Z0-9]+\.[ch]$ ]]
test $? -eq 1 || add_warning 1 "Avoid mentioning C source filenames"
# If the subject is oversimplified for a queue function OR queue.c is modified,
# and there is only one meaningful line, issue a warning.
if { [[ "${COMMIT_SUBJECT_TO_PROCESS}" =~ ^(Implement|Finish|Complete)[[:space:]]+q_[[:alnum:]_]+\(?\)?$ ]] || \
git diff --cached --name-only | grep -Eq '(^|/)queue\.c$'; } && [ "${NON_COMMENT_COUNT}" -le 1 ]; then
add_warning 1 "Commit message oversimplified. Use the commit message body to explain what and why."
fi

# 9. Do not start the subject line with whitespace
# ------------------------------------------------------------------------------

[[ ${COMMIT_SUBJECT_TO_PROCESS} =~ ^[[:blank:]]+ ]]
test $? -eq 1 || add_warning 1 "Do not start the subject line with whitespace"

# 10. Avoid single word commit messages in subject
# 10. Disallow backticks anywhere in the commit message.
# ------------------------------------------------------------------------------

word_count=$(echo "$COMMIT_SUBJECT_TO_PROCESS" | wc -w)
test "$word_count" -gt 1
test $? -eq 0 || add_warning 1 "Commit subject should contain more than one word. Summarize your changes"
if sed '/^[[:space:]]*#/d;/^[[:space:]]*$/d' "${COMMIT_MSG_FILE}" | grep -q "\`"; then
add_warning 1 "Avoid using backticks in commit messages"
fi

# 11. Avoid commit subject that simply states a file update (e.g. "Update console.c")
# ------------------------------------------------------------------------------

if [[ $COMMIT_SUBJECT_TO_PROCESS =~ ^Update[[:space:]]+([^[:space:]]+)$ ]]; then
if [[ ${COMMIT_SUBJECT_TO_PROCESS} =~ ^Update[[:space:]]+([^[:space:]]+)$ ]]; then
candidate="${BASH_REMATCH[1]}"
# Only warn if the candidate filename ends with .c or .h
if [[ $candidate =~ \.(c|h)$ ]]; then
Expand Down