diff --git a/scripts/commit-msg.hook b/scripts/commit-msg.hook index 17629cc1a..55f5ed36e 100755 --- a/scripts/commit-msg.hook +++ b/scripts/commit-msg.hook @@ -249,35 +249,51 @@ 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 # ------------------------------------------------------------------------------ @@ -285,17 +301,17 @@ done [[ ${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