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