Skip to content

Instantly share code, notes, and snippets.

@eduardosilva
Created April 24, 2023 13:58
Show Gist options
  • Save eduardosilva/39ce3ec8ab28baf0cff4e45f796a9068 to your computer and use it in GitHub Desktop.
Save eduardosilva/39ce3ec8ab28baf0cff4e45f796a9068 to your computer and use it in GitHub Desktop.
This script validates Git commit messages to ensure they are in Angular commit message format.
#!/bin/bash
#############################################################################################
# This script validates Git commit messages to ensure they are in Angular #
# commit message format. #
# #
# Angular commit message format: #
# type(scope): subject #
# <BLANK LINE> #
# body #
# <BLANK LINE> #
# footer #
# #
# For more information, see: #
# https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines #
# #
# #
# This script requires Bash to run. #
#############################################################################################
commit_msg_file=$1
# commit types and scopes
commit_types="docs|feat|fix|perf|refactor|test"
commit_scopes="vim|zsh|git|docker|bash|install" # modify this line to include the relevant scopes for your project.
function error_message() {
local message="$1"
local line_number="$2"
local line_content="$3"
printf "\033[0;31mERROR: %s\n" "$message"
printf "Line number: %s\n" "$line_number"
printf "Line content: %s\033[0m\n" "$line_content"
}
# header validations
header=$(head -n1 "$commit_msg_file")
# Set up header validation
header_regex="^$commit_types\($commit_scopes\)?: [^A-Z][^\.\n]{1,72}$"
header_match=$(echo "$header" | grep -E "$header_regex")
if [[ -z "$header_match" ]]; then
line_number=1
line_content="$header"
error_message "Commit message header does not match format" "$line_number" "$line_content"
exit 1
fi
# Set up body validation
body=$(sed -n '2,$p' "$commit_msg_file")
if [[ -n "$body" ]]; then
body_length=$(echo "$body" | wc -c)
if [[ $body_length -lt 20 ]]; then
line_number=2
line_content="$body"
error_message "Commit message body must be at least 20 characters long" "$line_number" "$line_content"
exit 1
fi
elif [[ "$header" != "docs"* ]]; then
line_number=2
error_message "Commit message body is mandatory for this commit type" "$line_number" ""
exit 1
fi
#!/bin/bash
# create a temporary file for the commit message
tmpfile=$(mktemp)
# test valid header and body
echo "docs(vim): add documentation for vim plugin" > $tmpfile
echo "This commit adds documentation for the Vim plugin, including usage instructions." >> $tmpfile
output=$(bash commit-msg.sh $tmpfile)
if [[ $output != "" ]]; then
echo "Test failed: expected empty output, but got '$output'"
exit 1
fi
# test invalid header format
echo "invalid header format" > $tmpfile
echo "This is an invalid commit message." >> $tmpfile
output=$(bash commit-msg.sh $tmpfile)
expected_output="ERROR: Commit message header does not match format"
if [[ $output != *"$expected_output"* ]]; then
echo "Test failed: expected output '$expected_output', but got '$output'"
exit 1
fi
# test invalid body length
echo "docs(bash): add documentation for Bash script" > $tmpfile
echo "This commit " >> $tmpfile
output=$(bash commit-msg.sh $tmpfile)
expected_output="ERROR: Commit message body must be at least 20 characters long"
if [[ $output != *"$expected_output"* ]]; then
echo "Test failed: expected output '$expected_output', but got '$output'"
exit 1
fi
# test missing body for non-docs commit type
echo "feat: add new feature" > $tmpfile
output=$(bash commit-msg.sh $tmpfile)
expected_output="ERROR: Commit message body is mandatory for this commit type"
if [[ $output != *"$expected_output"* ]]; then
echo "Test failed: expected output '$expected_output', but got '$output'"
exit 1
fi
# test missing body for commit type is not a doc
echo "feat: add documentation" > $tmpfile
output=$(bash commit-msg.sh $tmpfile)
expected_output="ERROR: Commit message body is mandatory for this commit type"
if [[ $output != *"$expected_output"* ]]; then
echo "Test failed: expected output '$expected_output', but got '$output'"
exit 1
fi
# clean up the temporary file
rm $tmpfile
echo "All tests passed!"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment