forked from WebKit/WebKit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprepare-commit-msg
More file actions
181 lines (141 loc) · 5.55 KB
/
prepare-commit-msg
File metadata and controls
181 lines (141 loc) · 5.55 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env {{ python }}
import os
import re
import subprocess
import sys
LOCATION = r'{{ location }}'
SPACING = 8
SCRIPTS = os.path.dirname(os.path.dirname(LOCATION))
sys.path.append(SCRIPTS)
from webkitpy.common.checkout.diff_parser import DiffParser
from webkitbugspy import radar
def get_bugs_string():
"""Determines what bug URLs to fill or suggest in a WebKit commit message."""
env = os.environ
need_the_bug_url = 'Need the bug URL (OOPS!).'
need_the_radar = 'Include a Radar link (OOPS!).'
has_radar = any([bool(regex.match(line))
for line in env.get('COMMIT_MESSAGE_BUG', '').splitlines()
for regex in radar.Tracker.RES])
if env.get('COMMIT_MESSAGE_BUG'):
if has_radar or not bool(radar.Tracker.radarclient()):
return env['COMMIT_MESSAGE_BUG']
else:
return env['COMMIT_MESSAGE_BUG'] + '\n' + need_the_radar
bugs_string = need_the_bug_url
if bool(radar.Tracker.radarclient()):
bugs_string += '\n' + need_the_radar
return bugs_string
def message_from_staged_changelogs():
try:
diff = subprocess.check_output(['git', 'diff', '--staged'])
except subprocess.CalledProcessError:
return ''
modified_files = DiffParser(diff.splitlines()).files
message = ''
for path, parsed_diff in modified_files.items():
if not path.endswith('ChangeLog'):
continue
# Ignore first line (date, name, email) and second line (empty).
diff_lines = parsed_diff.lines[2:]
# Get added lines and strip leading 8 characters indentation.
lines = [line[2][SPACING:] for line in diff_lines if not line[0]]
message += '\n'.join(lines)
return message
def message(source=None, sha=None):
msg = message_from_staged_changelogs()
if msg:
return msg
dirname = None
commit_message = []
try:
for line in subprocess.check_output(
['perl', os.path.join(SCRIPTS, 'prepare-ChangeLog'), '--no-write', '--only-files', '--delimiters'],
**(dict(encoding='utf-8') if sys.version_info > (3, 0) else dict())
).splitlines():
if line == '~':
dirname = None
continue
if line.startswith(' ' * SPACING):
if dirname:
line = line.replace('* ', '* {}/'.format(dirname))
commit_message.append(line[SPACING:])
continue
if line.endswith(':'):
dirname = line.split(':')[0]
continue
except subprocess.CalledProcessError:
return ''
bugs_string = get_bugs_string()
return '''{title}
{bugs}
Reviewed by NOBODY (OOPS!).
{content}
'''.format(
title=os.environ.get('COMMIT_MESSAGE_TITLE', '') or 'Need a short description (OOPS!).',
bugs=bugs_string,
content='\n'.join(commit_message) + os.environ.get('COMMIT_MESSAGE_CONTENT', ''),
)
def cherry_pick(content):
cherry_picked = os.environ.get('GIT_WEBKIT_CHERRY_PICKED')
bug = os.environ.get('GIT_WEBKIT_BUG')
if not cherry_picked or not bug:
LINK_RE = re.compile(r'^\S+:\/\/\S+\d+\S*$')
HASH_RE = re.compile(r'^# You are currently cherry-picking commit (?P<hash>[a-f0-9A-F]+)\.$')
for line in content.splitlines():
if not line:
continue
if not bug and LINK_RE.match(line):
bug = line
match = None if cherry_picked else HASH_RE.match(line)
if match:
cherry_picked = match.group('hash')
if bug and cherry_picked:
break
result = 'Cherry-pick {}. {}\n\n'.format(cherry_picked or '???', bug or '<bug>')
for line in content.splitlines():
if not line:
result += '\n'
continue
if line[0] != '#':
result += 4*' '
result += line + '\n'
return result
def main(file_name=None, source=None, sha=None):
with open(file_name, 'r') as commit_message_file:
content = commit_message_file.read()
if source not in (None, 'commit', 'template', 'merge'):
return 0
if source == 'merge' and os.environ.get('GIT_REFLOG_ACTION') == 'cherry-pick':
with open(file_name, 'w') as commit_message_file:
commit_message_file.write(cherry_pick(content))
return 0
if source == 'merge' and not content.startswith('Revert'):
return 0
if os.environ.get('GIT_EDITOR', '') == ':':
# When there's no editor being launched, do nothing.
return 0
with open(file_name, 'w') as commit_message_file:
if sha:
commit_message_file.write(subprocess.check_output(
['git', 'log', 'HEAD', '-1', '--pretty=format:%B'],
**(dict(encoding='utf-8') if sys.version_info > (3, 5) else dict())
))
else:
commit_message_file.write(message(source=source, sha=sha))
commit_message_file.write('''
# Please populate the above commit message. Lines starting
# with '#' will be ignored
''')
if sha:
for line in message(source=source, sha=sha).splitlines():
commit_message_file.write('# {}\n'.format(line))
commit_message_file.write('\n')
for line in subprocess.check_output(
['git', 'status'],
**(dict(encoding='utf-8') if sys.version_info > (3, 5) else dict())
).splitlines():
commit_message_file.write('# {}\n'.format(line))
return 0
if __name__ == '__main__':
sys.exit(main(*sys.argv[1:]))