#!/bin/sh
#
# This is an example Git hook for use with Rush.  To enable this hook, rename this file
# to "commit-msg" and then run "rush install", which will copy it from common/git-hooks
# to the .git/hooks folder.
#
# TO LEARN MORE ABOUT GIT HOOKS
#
# The Git documentation is here: https://git-scm.com/docs/githooks
# Some helpful resources: https://githooks.com
#
# ABOUT THIS EXAMPLE
#
# The commit-msg hook is called by "git commit" with one argument, the name of the file
# that has the commit message.  The hook should exit with non-zero status after issuing
# an appropriate message if it wants to stop the commit.  The hook is allowed to edit
# the commit message file.

# This example enforces that commit message should contain a minimum amount of
# description text.

# offical example
#if [ `cat $1 | wc -w` -lt 3 ]; then
#  echo ""
#  echo "Invalid commit message: The message must contain at least 3 words."
#	exit 1
#fi

# 新增 conventional-commit shell实现
# A commit-msg hook to check commit messages for Conventional Commits formatting
# reference https://github.com/compilerla/conventional-pre-commit/blob/main/conventional-pre-commit.sh

# list of Conventional Commits types
cc_types=("feat" "fix")
default_types=("build" "chore" "ci" "docs" "${cc_types[@]}" "perf" "refactor" "revert" "style" "test")
types=( "${cc_types[@]}" )

if [ $# -eq 1 ]; then
    types=( "${default_types[@]}" )
else
    # assume all args but the last are types
    while [ $# -gt 1 ]; do
        types+=( "$1" )
        shift
    done
fi

# the commit message file is the last remaining arg
msg_file="$1"

# join types with | to form regex ORs
r_types="($(IFS='|'; echo "${types[*]}"))"
# optional (scope)
r_scope="(\([[:alnum:] \/-]+\))?"
# optional breaking change indicator and colon delimiter
r_delim='!?:'
# subject line, body, footer
r_subject=" [[:alnum:]].+"
# the full regex pattern
pattern="^$r_types$r_scope$r_delim$r_subject$"

# Check if commit is conventional commit
if grep -Eq "$pattern" "$msg_file"; then
    exit 0
fi

echo "[Commit message] $( cat "$msg_file" )"
echo "
Your commit message does not follow Conventional Commits formatting
https://www.conventionalcommits.org/
Conventional Commits start with one of the below types, followed by a colon,
followed by the commit message:
    $(IFS=' '; echo "${types[*]}")
Example commit message adding a feature:
    feat: implement new API
Example commit message fixing an issue:
    fix: remove infinite loop
Optionally, include a scope in parentheses after the type for more context:
    fix(account): remove infinite loop
"
exit 1