]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - scripts/commitcheck.sh
initramfs/debian: use panic() instead of directly calling /bin/sh
[FreeBSD/FreeBSD.git] / scripts / commitcheck.sh
1 #!/bin/bash
2
3 REF="HEAD"
4
5 # test a url
6 function test_url()
7 {
8     url="$1"
9     if ! curl --output /dev/null --max-time 60 \
10                 --silent --head --fail "$url" ; then
11         echo "\"$url\" is unreachable"
12         return 1
13     fi
14
15     return 0
16 }
17
18 # test commit body for length
19 # lines containing urls are exempt for the length limit.
20 function test_commit_bodylength()
21 {
22     length="72"
23     body=$(git log -n 1 --pretty=%b "$REF" | grep -Ev "http(s)*://" | grep -E -m 1 ".{$((length + 1))}")
24     if [ -n "$body" ]; then
25         echo "error: commit message body contains line over ${length} characters"
26         return 1
27     fi
28
29     return 0
30 }
31
32 # check for a tagged line
33 function check_tagged_line()
34 {
35     regex='^\s*'"$1"':\s[[:print:]]+\s<[[:graph:]]+>$'
36     foundline=$(git log -n 1 "$REF" | grep -E -m 1 "$regex")
37     if [ -z "$foundline" ]; then
38         echo "error: missing \"$1\""
39         return 1
40     fi
41
42     return 0
43 }
44
45 # check for a tagged line and check that the link is valid
46 function check_tagged_line_with_url()
47 {
48     regex='^\s*'"$1"':\s\K([[:graph:]]+)$'
49     foundline=$(git log -n 1 "$REF" | grep -Po "$regex")
50     if [ -z "$foundline" ]; then
51         echo "error: missing \"$1\""
52         return 1
53     fi
54
55     OLDIFS=$IFS
56     IFS=$'\n'
57     for url in $(echo -e "$foundline"); do
58         if ! test_url "$url"; then
59             return 1
60         fi
61     done
62     IFS=$OLDIFS
63
64     return 0
65 }
66
67 # check commit message for a normal commit
68 function new_change_commit()
69 {
70     error=0
71
72     # subject is not longer than 72 characters
73     long_subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '.{73}')
74     if [ -n "$long_subject" ]; then
75         echo "error: commit subject over 72 characters"
76         error=1
77     fi
78
79     # need a signed off by
80     if ! check_tagged_line "Signed-off-by" ; then
81         error=1
82     fi
83
84     # ensure that no lines in the body of the commit are over 72 characters
85     if ! test_commit_bodylength ; then
86         error=1
87     fi
88
89     return $error
90 }
91
92 function is_openzfs_port()
93 {
94     # subject starts with OpenZFS means it's an openzfs port
95     subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^OpenZFS')
96     if [ -n "$subject" ]; then
97         return 0
98     fi
99
100     return 1
101 }
102
103 function openzfs_port_commit()
104 {
105     error=0
106
107     # subject starts with OpenZFS dddd
108     subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^OpenZFS [[:digit:]]+(, [[:digit:]]+)* - ')
109     if [ -z "$subject" ]; then
110         echo "error: OpenZFS patch ports must have a subject line that starts with \"OpenZFS dddd - \""
111         error=1
112     fi
113
114     # need an authored by line
115     if ! check_tagged_line "Authored by" ; then
116         error=1
117     fi
118
119     # need a reviewed by line
120     if ! check_tagged_line "Reviewed by" ; then
121         error=1
122     fi
123
124     # need ported by line
125     if ! check_tagged_line "Ported-by" ; then
126         error=1
127     fi
128
129     # need a url to openzfs commit and it should be valid
130     if ! check_tagged_line_with_url "OpenZFS-commit" ; then
131         error=1
132     fi
133
134     # need a url to illumos issue and it should be valid
135     if ! check_tagged_line_with_url "OpenZFS-issue" ; then
136         error=1
137     fi
138
139     return $error
140 }
141
142 function is_coverity_fix()
143 {
144     # subject starts with Fix coverity defects means it's a coverity fix
145     subject=$(git log -n 1 --pretty=%s "$REF" | grep -E -m 1 '^Fix coverity defects')
146     if [ -n "$subject" ]; then
147         return 0
148     fi
149
150     return 1
151 }
152
153 function coverity_fix_commit()
154 {
155     error=0
156
157     # subject starts with Fix coverity defects: CID dddd, dddd...
158     subject=$(git log -n 1 --pretty=%s "$REF" |
159         grep -E -m 1 'Fix coverity defects: CID [[:digit:]]+(, [[:digit:]]+)*')
160     if [ -z "$subject" ]; then
161         echo "error: Coverity defect fixes must have a subject line that starts with \"Fix coverity defects: CID dddd\""
162         error=1
163     fi
164
165     # need a signed off by
166     if ! check_tagged_line "Signed-off-by" ; then
167         error=1
168     fi
169
170     # test each summary line for the proper format
171     OLDIFS=$IFS
172     IFS=$'\n'
173     for line in $(git log -n 1 --pretty=%b "$REF" | grep -E '^CID'); do
174         echo "$line" | grep -E '^CID [[:digit:]]+: ([[:graph:]]+|[[:space:]])+ \(([[:upper:]]|\_)+\)' > /dev/null
175         # shellcheck disable=SC2181
176         if [[ $? -ne 0 ]]; then
177             echo "error: commit message has an improperly formatted CID defect line"
178             error=1
179         fi
180     done
181     IFS=$OLDIFS
182
183     # ensure that no lines in the body of the commit are over 72 characters
184     if ! test_commit_bodylength; then
185         error=1
186     fi
187
188     return $error
189 }
190
191 if [ -n "$1" ]; then
192     REF="$1"
193 fi
194
195 # if openzfs port, test against that
196 if is_openzfs_port; then
197     if ! openzfs_port_commit ; then
198         exit 1
199     else
200         exit 0
201     fi
202 fi
203
204 # if coverity fix, test against that
205 if is_coverity_fix; then
206     if ! coverity_fix_commit; then
207         exit 1
208     else
209         exit 0
210     fi
211 fi
212
213 # have a normal commit
214 if ! new_change_commit ; then
215     exit 1
216 fi
217
218 exit 0