pagure-new/pagure/hooks/files/pagure_hook.py

203 lines
6.4 KiB
Python
Executable file

#! /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:])