204 lines
6.4 KiB
Python
204 lines
6.4 KiB
Python
|
#! /usr/bin/env python2
|
||
|
|
||
|
|
||
|
"""Pagure specific hook to add comment on issues if the commits fixes or
|
||
|
relates to an issue.
|
||
|
"""
|
||
|
|
||
|
import os
|
||
|
import sys
|
||
|
|
||
|
import pygit2
|
||
|
|
||
|
from sqlalchemy.exc import SQLAlchemyError
|
||
|
|
||
|
if 'PAGURE_CONFIG' not in os.environ \
|
||
|
and os.path.exists('/etc/pagure/pagure.cfg'):
|
||
|
os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
|
||
|
|
||
|
|
||
|
import pagure
|
||
|
import pagure.exceptions
|
||
|
import pagure.lib.link
|
||
|
|
||
|
|
||
|
abspath = os.path.abspath(os.environ['GIT_DIR'])
|
||
|
|
||
|
|
||
|
def generate_revision_change_log(new_commits_list):
|
||
|
|
||
|
print 'Detailed log of new commits:\n\n'
|
||
|
commitid = None
|
||
|
for line in pagure.lib.git.read_git_lines(
|
||
|
['log', '--no-walk'] + new_commits_list + ['--'], abspath):
|
||
|
if line.startswith('commit'):
|
||
|
commitid = line.split('commit ')[-1]
|
||
|
|
||
|
line = line.strip()
|
||
|
|
||
|
print '*', line
|
||
|
for relation in pagure.lib.link.get_relation(
|
||
|
pagure.SESSION,
|
||
|
pagure.lib.git.get_repo_name(abspath),
|
||
|
pagure.lib.git.get_username(abspath),
|
||
|
pagure.lib.git.get_repo_namespace(abspath),
|
||
|
line,
|
||
|
'fixes',
|
||
|
include_prs=True):
|
||
|
fixes_relation(commitid, relation,
|
||
|
pagure.APP.config.get('APP_URL'))
|
||
|
|
||
|
for issue in pagure.lib.link.get_relation(
|
||
|
pagure.SESSION,
|
||
|
pagure.lib.git.get_repo_name(abspath),
|
||
|
pagure.lib.git.get_username(abspath),
|
||
|
pagure.lib.git.get_repo_namespace(abspath),
|
||
|
line,
|
||
|
'relates'):
|
||
|
relates_commit(commitid, issue, pagure.APP.config.get('APP_URL'))
|
||
|
|
||
|
|
||
|
def relates_commit(commitid, issue, app_url=None):
|
||
|
''' Add a comment to an issue that this commit relates to it. '''
|
||
|
|
||
|
url = '../%s' % commitid[:8]
|
||
|
if app_url:
|
||
|
if app_url.endswith('/'):
|
||
|
app_url = app_url[:-1]
|
||
|
project = issue.project.fullname
|
||
|
if issue.project.is_fork:
|
||
|
project = 'fork/%s' % project
|
||
|
url = '%s/%s/c/%s' % (app_url, project, commitid[:8])
|
||
|
|
||
|
comment = ''' Commit [%s](%s) relates to this ticket''' % (
|
||
|
commitid[:8], url)
|
||
|
|
||
|
try:
|
||
|
pagure.lib.add_issue_comment(
|
||
|
pagure.SESSION,
|
||
|
issue=issue,
|
||
|
comment=comment,
|
||
|
user=pagure.lib.git.get_author_email(commitid, abspath),
|
||
|
ticketfolder=pagure.APP.config['TICKETS_FOLDER'],
|
||
|
)
|
||
|
pagure.SESSION.commit()
|
||
|
except pagure.exceptions.PagureException as err:
|
||
|
print err
|
||
|
except SQLAlchemyError as err: # pragma: no cover
|
||
|
pagure.SESSION.rollback()
|
||
|
pagure.APP.logger.exception(err)
|
||
|
|
||
|
|
||
|
def fixes_relation(commitid, relation, app_url=None):
|
||
|
''' Add a comment to an issue or PR that this commit fixes it and update
|
||
|
the status if the commit is in the master branch. '''
|
||
|
|
||
|
url = '../c/%s' % commitid[:8]
|
||
|
if app_url:
|
||
|
if app_url.endswith('/'):
|
||
|
app_url = app_url[:-1]
|
||
|
project = relation.project.fullname
|
||
|
if relation.project.is_fork:
|
||
|
project = 'fork/%s' % project
|
||
|
url = '%s/%s/c/%s' % (app_url, project, commitid[:8])
|
||
|
|
||
|
comment = ''' Commit [%s](%s) fixes this %s''' % (
|
||
|
commitid[:8], url, relation.isa)
|
||
|
|
||
|
try:
|
||
|
if relation.isa == 'issue':
|
||
|
pagure.lib.add_issue_comment(
|
||
|
pagure.SESSION,
|
||
|
issue=relation,
|
||
|
comment=comment,
|
||
|
user=pagure.lib.git.get_author_email(commitid, abspath),
|
||
|
ticketfolder=pagure.APP.config['TICKETS_FOLDER'],
|
||
|
)
|
||
|
elif relation.isa == 'pull-request':
|
||
|
pagure.lib.add_pull_request_comment(
|
||
|
pagure.SESSION,
|
||
|
request=relation,
|
||
|
commit=None,
|
||
|
tree_id=None,
|
||
|
filename=None,
|
||
|
row=None,
|
||
|
comment=comment,
|
||
|
user=pagure.lib.git.get_author_email(commitid, abspath),
|
||
|
requestfolder=pagure.APP.config['REQUESTS_FOLDER'],
|
||
|
)
|
||
|
pagure.SESSION.commit()
|
||
|
except pagure.exceptions.PagureException as err:
|
||
|
print err
|
||
|
except SQLAlchemyError as err: # pragma: no cover
|
||
|
pagure.SESSION.rollback()
|
||
|
pagure.APP.logger.exception(err)
|
||
|
|
||
|
try:
|
||
|
if relation.isa == 'issue':
|
||
|
pagure.lib.edit_issue(
|
||
|
pagure.SESSION,
|
||
|
relation,
|
||
|
ticketfolder=pagure.APP.config['TICKETS_FOLDER'],
|
||
|
user=pagure.lib.git.get_author_email(commitid, abspath),
|
||
|
status='Fixed')
|
||
|
elif relation.isa == 'pull-request':
|
||
|
pagure.lib.close_pull_request(
|
||
|
pagure.SESSION,
|
||
|
relation,
|
||
|
requestfolder=pagure.APP.config['REQUESTS_FOLDER'],
|
||
|
user=pagure.lib.git.get_author_email(commitid, abspath),
|
||
|
merged=True)
|
||
|
pagure.SESSION.commit()
|
||
|
except pagure.exceptions.PagureException as err:
|
||
|
print err
|
||
|
except SQLAlchemyError as err: # pragma: no cover
|
||
|
pagure.SESSION.rollback()
|
||
|
pagure.APP.logger.exception(err)
|
||
|
|
||
|
|
||
|
def run_as_post_receive_hook():
|
||
|
|
||
|
for line in sys.stdin:
|
||
|
if pagure.APP.config.get('HOOK_DEBUG', False):
|
||
|
print line
|
||
|
(oldrev, newrev, refname) = line.strip().split(' ', 2)
|
||
|
|
||
|
if pagure.APP.config.get('HOOK_DEBUG', False):
|
||
|
print ' -- Old rev'
|
||
|
print oldrev
|
||
|
print ' -- New rev'
|
||
|
print newrev
|
||
|
print ' -- Ref name'
|
||
|
print refname
|
||
|
|
||
|
# Retrieve the default branch
|
||
|
repo_obj = pygit2.Repository(abspath)
|
||
|
default_branch = None
|
||
|
if not repo_obj.is_empty and not repo_obj.head_is_unborn:
|
||
|
default_branch = repo_obj.head.shorthand
|
||
|
|
||
|
# Skip all branch but the default one
|
||
|
refname = refname.replace('refs/heads/', '')
|
||
|
if refname != default_branch:
|
||
|
continue
|
||
|
|
||
|
if set(newrev) == set(['0']):
|
||
|
print "Deleting a reference/branch, so we won't run the "\
|
||
|
"pagure hook"
|
||
|
return
|
||
|
|
||
|
generate_revision_change_log(
|
||
|
pagure.lib.git.get_revs_between(oldrev, newrev, abspath, refname))
|
||
|
|
||
|
if pagure.APP.config.get('HOOK_DEBUG', False):
|
||
|
print 'repo:', pagure.lib.git.get_repo_name(abspath)
|
||
|
print 'user:', pagure.lib.git.get_username(abspath)
|
||
|
|
||
|
|
||
|
def main(args):
|
||
|
run_as_post_receive_hook()
|
||
|
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main(sys.argv[1:])
|