summaryrefslogtreecommitdiff
path: root/misc/srothwell_check_patches.sh
blob: 0bd89e6506a1b2bc8308dceb20f14a0da8800768 (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
#!/bin/bash

if [ "$#" -lt 1 ]; then
        printf 'Usage: %s <commit range>\n', "$0" 1>&2
        exit 1
fi

commits=$(git rev-list --no-merges -i --grep='^[[:space:]]*Fixes:' "$@")
if [ -z "$commits" ]; then
        exit 0
fi

# This should be a git tree that contains *only* Linus' tree
Linus_tree="${HOME}/kernels/linus.git"
split_re='^([[:xdigit:]]+)[[:space:]]+(.*)$'
nl=$'\n'

# Strip the leading and training spaces from a string
strip_spaces()
{
	[[ "$1" =~ ^[[:space:]]*(.*[^[:space:]])[[:space:]]*$ ]]
	echo "${BASH_REMATCH[1]}"
}

for c in $commits; do

	commit_log=$(git log -1 --format='%h ("%s")' "$c")
	commit_msg="In commit

  $commit_log

"

	fixes_lines=$(git log -1 --format='%B' "$c" |
			grep -i '^[[:space:]]*Fixes:')

	while read -r fline; do
		f=$(echo "$fline" | sed 's/^[[:space:]]*Fixes:[[:space:]]*//i')
		fixes_msg="Fixes tag

  $fline

has these problem(s):

"
		sha=
		subject=
		msg=
		[[ "$f" =~ $split_re ]]
		sha="${BASH_REMATCH[1]}"
		subject="${BASH_REMATCH[2]}"

		if [ -z "$sha" ]; then
			printf '%s%s  - %s\n' "$commit_msg" "$fixes_msg" 'No SHA1 recognised'
			commit_msg=''
			continue
		fi
		if ! git rev-parse -q --verify "$sha" >/dev/null; then
			printf '%s%s  - %s\n' "$commit_msg" "$fixes_msg" 'Target SHA1 does not exist'
			commit_msg=''
			continue
		fi

		if [ "${#sha}" -lt 12 ]; then
			msg="${msg:+${msg}${nl}}  - SHA1 should be at least 12 digits long"
		fi
		# reduce the subject to the part between () if there
		if [[ "$subject" =~ ^\((.*)\) ]]; then
			subject="${BASH_REMATCH[1]}"
		elif [[ "$subject" =~ ^\((.*) ]]; then
			subject="${BASH_REMATCH[1]}"
			msg="${msg:+${msg}${nl}}  - Subject has leading but no trailing parentheses"
		fi

		# strip matching quotes at the start and end of the subject
		# the unicode characters in the classes are
		# U+201C LEFT DOUBLE QUOTATION MARK
		# U+201D RIGHT DOUBLE QUOTATION MARK
		# U+2018 LEFT SINGLE QUOTATION MARK
		# U+2019 RIGHT SINGLE QUOTATION MARK
		re1=$'^[\"\u201C](.*)[\"\u201D]$'
		re2=$'^[\'\u2018](.*)[\'\u2019]$'
		re3=$'^[\"\'\u201C\u2018](.*)$'
		if [[ "$subject" =~ $re1 ]]; then
			subject="${BASH_REMATCH[1]}"
		elif [[ "$subject" =~ $re2 ]]; then
			subject="${BASH_REMATCH[1]}"
		elif [[ "$subject" =~ $re3 ]]; then
			subject="${BASH_REMATCH[1]}"
			msg="${msg:+${msg}${nl}}  - Subject has leading but no trailing quotes"
		fi

		subject=$(strip_spaces "$subject")

		target_subject=$(git log -1 --format='%s' "$sha")
		target_subject=$(strip_spaces "$target_subject")

		# match with ellipses
		case "$subject" in
		*...)	subject="${subject%...}"
			target_subject="${target_subject:0:${#subject}}"
			;;
		...*)	subject="${subject#...}"
			target_subject="${target_subject: -${#subject}}"
			;;
		*\ ...\ *)
			s1="${subject% ... *}"
			s2="${subject#* ... }"
			subject="$s1 $s2"
			t1="${target_subject:0:${#s1}}"
			t2="${target_subject: -${#s2}}"
			target_subject="$t1 $t2"
			;;
		esac
		subject=$(strip_spaces "$subject")
		target_subject=$(strip_spaces "$target_subject")

		if [ "$subject" != "${target_subject:0:${#subject}}" ]; then
			msg="${msg:+${msg}${nl}}  - Subject does not match target commit subject"
		fi
		lsha=$(cd "$Linus_tree" && git rev-parse -q --verify "$sha")
		if [ -z "$lsha" ]; then
			count=$(git rev-list --count "$sha".."$c")
			if [ "$count" -eq 0 ]; then
				msg="${msg:+${msg}${nl}}  - Target is not an ancestor of this commit"
			fi
		fi
		if [ "$msg" ]; then
			printf '%s%s%s\n' "$commit_msg" "$fixes_msg" "$msg"
			commit_msg=''
		fi
	done <<< "$fixes_lines"
done

exit 0