blob: 4910818fc2635083b605ab7cbf992ce99662ebc7 [file] [log] [blame] [edit]
#!/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:]))