1+ #! /usr/bin/env bash
2+
3+ # list of Conventional Commits types
4+ cc_types=(" feat" " fix" )
5+ default_types=(" build" " chore" " ci" " docs" " ${cc_types[@]} " " perf" " refactor" " revert" " style" " test" )
6+ types=( " ${cc_types[@]} " )
7+
8+ if [ $# -eq 1 ]; then
9+ types=( " ${default_types[@]} " )
10+ else
11+ # assume all args but the last are types
12+ while [ $# -gt 1 ]; do
13+ types+=( " $1 " )
14+ shift
15+ done
16+ fi
17+
18+ # the commit message file is the last remaining arg
19+ msg_file=" $1 "
20+
21+ # join types with | to form regex ORs
22+ r_types=" ($( IFS=' |' ; echo " ${types[*]} " ) )"
23+ # optional (scope)
24+ r_scope=" (\([[:alnum:] \/-]+\))?"
25+ # optional breaking change indicator and colon delimiter
26+ r_delim=' !?:'
27+ # subject line, body, footer
28+ r_subject=" [[:alnum:]].+"
29+ # the full regex pattern
30+ pattern=" ^$r_types$r_scope$r_delim$r_subject $"
31+
32+ # Check if commit is conventional commit
33+ if grep -Eq " $pattern " " $msg_file " ; then
34+ exit 0
35+ fi
36+
37+ echo " [Commit message] $( cat " $msg_file " ) "
38+ echo "
39+ Your commit message does not follow Conventional Commits formatting
40+ https://www.conventionalcommits.org/
41+ Conventional Commits start with one of the below types, followed by a colon,
42+ followed by the commit message:
43+ $( IFS=' ' ; echo " ${types[*]} " )
44+ Example commit message adding a feature:
45+ feat: implement new API
46+ Example commit message fixing an issue:
47+ fix: remove infinite loop
48+ Optionally, include a scope in parentheses after the type for more context:
49+ fix(account): remove infinite loop
50+ "
51+ exit 1
0 commit comments