|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/** |
|
4
|
|
|
* Simple Machines Forum (SMF) |
|
5
|
|
|
* |
|
6
|
|
|
* @package SMF |
|
7
|
|
|
* @author Simple Machines https://www.simplemachines.org |
|
8
|
|
|
* @copyright 2020 Simple Machines and individual contributors |
|
9
|
|
|
* @license https://www.simplemachines.org/about/smf/license.php BSD |
|
10
|
|
|
* |
|
11
|
|
|
* @version 2.1 RC3 |
|
12
|
|
|
*/ |
|
13
|
|
|
|
|
14
|
|
|
// Debug stuff. |
|
15
|
|
|
define('DEBUG_MODE', false); |
|
16
|
|
|
|
|
17
|
|
|
if (DEBUG_MODE) |
|
18
|
|
|
debugPrint("--- DEBUG MSGS START ---"); |
|
19
|
|
|
|
|
20
|
|
|
// First, lets do a basic test. This is non GPG signed commits. |
|
21
|
|
|
$signedoff = find_signed_off(); |
|
22
|
|
|
|
|
23
|
|
|
// Now Try to test for the GPG if we don't have a message. |
|
24
|
|
|
if (empty($signedoff)) |
|
25
|
|
|
$signedoff = find_gpg(); |
|
26
|
|
|
|
|
27
|
|
|
// Nothing yet? Lets ask your parents. |
|
28
|
|
|
if (empty($signedoff) && isset($_SERVER['argv'], $_SERVER['argv'][1]) && $_SERVER['argv'][1] == 'travis') |
|
29
|
|
|
$signedoff = find_signed_off_parents(); |
|
30
|
|
|
|
|
31
|
|
|
if (DEBUG_MODE) |
|
32
|
|
|
debugPrint("--- DEBUG MSGS END ---"); |
|
33
|
|
|
|
|
34
|
|
|
// Nothing? Well darn. |
|
35
|
|
|
if (empty($signedoff)) |
|
36
|
|
|
{ |
|
37
|
|
|
fwrite(STDERR, 'Error: Signed-off-by not found in commit message'); |
|
38
|
|
|
exit(1); |
|
39
|
|
|
} |
|
40
|
|
|
elseif (DEBUG_MODE) |
|
41
|
|
|
debugPrint('Valid signed off found'); |
|
42
|
|
|
|
|
43
|
|
|
// Find a commit by Signed Off |
|
44
|
|
|
function find_signed_off($commit = 'HEAD', $childs = array(), $level = 0) |
|
45
|
|
|
{ |
|
46
|
|
|
$commit = trim($commit); |
|
47
|
|
|
|
|
48
|
|
|
// Where we are at. |
|
49
|
|
|
debugPrint('Attempting to find signed off on commit ' . $commit); |
|
50
|
|
|
|
|
51
|
|
|
// To many recrusions here. |
|
52
|
|
|
if ($level > 10) |
|
53
|
|
|
{ |
|
54
|
|
|
debugPrint('Recusion limit exceeded on find_signed_off'); |
|
55
|
|
|
return false; |
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
// What string tests should we look for? |
|
59
|
|
|
$stringTests = array('Signed-off-by:', 'Signed by'); |
|
60
|
|
|
|
|
61
|
|
|
// Get message data and clean it up, should only need the last line. |
|
62
|
|
|
$message = trim(shell_exec('git show -s --format=%B ' . $commit)); |
|
63
|
|
|
$lines = explode("\n", trim(str_replace("\r", "\n", $message))); |
|
64
|
|
|
$lastLine = $lines[count($lines) - 1]; |
|
65
|
|
|
|
|
66
|
|
|
// Debug info. |
|
67
|
|
|
debugPrint('Testing line "' . $lastLine . '"'); |
|
68
|
|
|
|
|
69
|
|
|
// loop through each test and find one. |
|
70
|
|
|
$result = false; |
|
71
|
|
|
foreach ($stringTests as $testedString) |
|
72
|
|
|
{ |
|
73
|
|
|
debugPrint('Testing "' . $testedString . '"'); |
|
74
|
|
|
|
|
75
|
|
|
$result = stripos($lastLine, $testedString); |
|
76
|
|
|
|
|
77
|
|
|
// We got a result. |
|
78
|
|
|
if ($result !== false) |
|
79
|
|
|
{ |
|
80
|
|
|
debugPrint('Found "' . $testedString . '"'); |
|
81
|
|
|
break; |
|
82
|
|
|
} |
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
// Debugger. |
|
86
|
|
|
$debugMsgs = array( |
|
87
|
|
|
'raw body' => '"' . rtrim(shell_exec('git show -s --format=%B ' . $commit)) . '"', |
|
88
|
|
|
'body' => '"' . rtrim(shell_exec('git show -s --format=%b ' . $commit)) . '"', |
|
89
|
|
|
'commit notes' => '"' . rtrim(shell_exec('git show -s --format=%N ' . $commit)) . '"', |
|
90
|
|
|
'ref names' => '"' . rtrim(shell_exec('git show -s --format=%d ' . $commit)) . '"', |
|
91
|
|
|
'commit hash' => '"' . rtrim(shell_exec('git show -s --format=%H ' . $commit)) . '"', |
|
92
|
|
|
'tree hash' => '"' . rtrim(shell_exec('git show -s --format=%T ' . $commit)) . '"', |
|
93
|
|
|
'parent hash' => '"' . rtrim(shell_exec('git show -s --format=%P ' . $commit)) . '"', |
|
94
|
|
|
'result' => '"' . $result . '"', |
|
|
|
|
|
|
95
|
|
|
'testedString' => '"' . $testedString . '"', |
|
|
|
|
|
|
96
|
|
|
); |
|
97
|
|
|
debugPrint('Commit ' . $commit . ' at time ' . time() . ": " . rtrim(print_r($debugMsgs, true))); |
|
98
|
|
|
|
|
99
|
|
|
|
|
100
|
|
|
// No result and found a merge? Lets go deeper. |
|
101
|
|
|
if ($result === false && preg_match('~Merge ([A-Za-z0-9]{40}) into ([A-Za-z0-9]{40})~i', $lastLine, $merges)) |
|
102
|
|
|
{ |
|
103
|
|
|
debugPrint('Found Merge, attempting to get more parent commit: ' . $merges[1]); |
|
104
|
|
|
|
|
105
|
|
|
return find_signed_off($merges[1], array_merge(array($merges[1]), $childs), ++$level); |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
return $result !== false; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
// Find a commit by GPG |
|
112
|
|
|
function find_gpg($commit = 'HEAD', $childs = array()) |
|
|
|
|
|
|
113
|
|
|
{ |
|
114
|
|
|
$commit = trim($commit); |
|
115
|
|
|
|
|
116
|
|
|
debugPrint('Attempting to Find GPG on commit ' . $commit); |
|
117
|
|
|
|
|
118
|
|
|
// Get verify commit data. |
|
119
|
|
|
$message = trim(shell_exec('git verify-commit ' . $commit . ' -v --raw')); |
|
120
|
|
|
|
|
121
|
|
|
// Should we actually test for gpg results? Perhaps, but it seems doing that with travis may fail since it has no way to verify a GPG signature from GitHub. GitHub should have prevented a bad GPG from making a commit to a authors repository and could be trusted in most cases it seems. |
|
122
|
|
|
$result = strlen($message) > 0; |
|
123
|
|
|
|
|
124
|
|
|
// Debugger. |
|
125
|
|
|
$debugMsgs = array( |
|
126
|
|
|
// Raw body. |
|
127
|
|
|
'verify-commit' => '"' . rtrim(shell_exec('git verify-commit ' . $commit . ' -v --raw')) . '"', |
|
128
|
|
|
// Result. |
|
129
|
|
|
'result' => '"' . $result . '"', |
|
130
|
|
|
// Last tested string, or the correct string. |
|
131
|
|
|
'message' => '"' . $message . '"', |
|
132
|
|
|
); |
|
133
|
|
|
debugPrint('Commit ' . $commit . ' at time ' . time() . ": " . rtrim(print_r($debugMsgs, true))); |
|
134
|
|
|
|
|
135
|
|
|
return $result; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
// Looks at all the parents, and tries to find a signed off by somewhere. |
|
139
|
|
|
function find_signed_off_parents($commit = 'HEAD') |
|
140
|
|
|
{ |
|
141
|
|
|
$commit = trim($commit); |
|
142
|
|
|
|
|
143
|
|
|
debugPrint('Attempting to find parents on commit ' . $commit); |
|
144
|
|
|
|
|
145
|
|
|
$parentsRaw = rtrim(shell_exec('git show -s --format=%P ' . $commit)); |
|
146
|
|
|
$parents = explode(' ', $parentsRaw); |
|
147
|
|
|
|
|
148
|
|
|
// Test each one. |
|
149
|
|
|
foreach ($parents as $p) |
|
150
|
|
|
{ |
|
151
|
|
|
$p = trim($p); |
|
152
|
|
|
debugPrint('Testing parent of ' . $commit . ' for signed off'); |
|
153
|
|
|
|
|
154
|
|
|
// Basic tests. |
|
155
|
|
|
$test = find_signed_off($p); |
|
156
|
|
|
|
|
157
|
|
|
// No, maybe it has a GPG parent. |
|
158
|
|
|
if (empty($test)) |
|
159
|
|
|
$test = find_gpg($p); |
|
160
|
|
|
|
|
161
|
|
|
if (!empty($test)) |
|
162
|
|
|
return $test; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
// Lucked out. |
|
166
|
|
|
return false; |
|
167
|
|
|
} |
|
168
|
|
|
|
|
169
|
|
|
// Print a debug line |
|
170
|
|
|
function debugPrint($msg) |
|
171
|
|
|
{ |
|
172
|
|
|
if (DEBUG_MODE) |
|
173
|
|
|
echo $msg, "\n"; |
|
174
|
|
|
} |