summaryrefslogtreecommitdiffstats
path: root/scripts/commitcheck.sh
blob: 5bef3375d9f7cf877fc32876149172e85db1f370 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/bash

REF="HEAD"

# test a url
function test_url()
{
    url="$1"
    if ! curl --output /dev/null --max-time 60 \
		--silent --head --fail "$url" ; then
        echo "\"$url\" is unreachable"
        return 1
    fi

    return 0
}

# check for a tagged line
function check_tagged_line()
{
    regex='^\s*'"$1"':\s[[:print:]]+\s<[[:graph:]]+>$'
    foundline=$(git log -n 1 "$REF" | egrep -m 1 "$regex")
    if [ -z "$foundline" ]; then
        echo "error: missing \"$1\""
        return 1
    fi

    return 0
}

# check for a tagged line and check that the link is valid
function check_tagged_line_with_url ()
{
    regex='^\s*'"$1"':\s\K([[:graph:]]+)$'
    foundline=$(git log -n 1 "$REF" | grep -Po "$regex")
    if [ -z "$foundline" ]; then
        echo "error: missing \"$1\""
        return 1
    fi

    if ! test_url "$foundline"; then
        return 1
    fi

    return 0
}

# check commit message for a normal commit
function new_change_commit()
{
    error=0

    # subject is not longer than 50 characters
    long_subject=$(git log -n 1 --pretty=%s "$REF" | egrep -m 1 '.{51}')
    if [ -n "$long_subject" ]; then
        echo "error: commit subject over 50 characters"
        error=1
    fi

    # need a signed off by
    if ! check_tagged_line "Signed-off-by" ; then
        error=1
    fi

    # ensure that no lines in the body of the commit are over 72 characters
    body=$(git log -n 1 --pretty=%b "$REF" | egrep -m 1 '.{73}')
    if [ -n "$body" ]; then
        echo "error: commit message body contains line over 72 characters"
        error=1
    fi

    return $error
}

function is_openzfs_port()
{
    # subject starts with OpenZFS means it's an openzfs port
    subject=$(git log -n 1 --pretty=%s "$REF" | egrep -m 1 '^OpenZFS')
    if [ -n "$subject" ]; then
        return 0
    fi

    return 1
}

function openzfs_port_commit()
{
    # subject starts with OpenZFS dddd
    subject=$(git log -n 1 --pretty=%s "$REF" | egrep -m 1 '^OpenZFS [[:digit:]]+ - ')
    if [ -z "$subject" ]; then
        echo "OpenZFS patch ports must have a summary that starts with \"OpenZFS dddd - \""
        error=1
    fi

    # need an authored by line
    if ! check_tagged_line "Authored by" ; then
        error=1
    fi

    # need a reviewed by line
    if ! check_tagged_line "Reviewed by" ; then
        error=1
    fi

    # need a approved by line
    if ! check_tagged_line "Approved by" ; then
        error=1
    fi

    # need ported by line
    if ! check_tagged_line "Ported-by" ; then
        error=1
    fi

    # need a url to openzfs commit and it should be valid
    if ! check_tagged_line_with_url "OpenZFS-commit" ; then
        error=1
    fi

    # need a url to illumos issue and it should be valid
    if ! check_tagged_line_with_url "OpenZFS-issue" ; then
        error=1
    fi

    return $error
}

if [ -n "$1" ]; then
    REF="$1"
fi

# if openzfs port, test against that
if is_openzfs_port; then
    if ! openzfs_port_commit ; then
        exit 1
    else
        exit 0
    fi
fi

# have a normal commit
if ! new_change_commit ; then
    exit 1
fi

exit 0