123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #!/usr/bin/env python
- """Pagure specific hook to add comment on issues if the commits fixes or
- relates to an issue.
- """
- from __future__ import print_function, unicode_literals
- import logging
- 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.config # noqa: E402
- import pagure.exceptions # noqa: E402
- import pagure.lib.link # noqa: E402
- _log = logging.getLogger(__name__)
- _config = pagure.config.config
- 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()
- session = pagure.lib.create_session(_config['DB_URL'])
- print('*', line)
- for relation in pagure.lib.link.get_relation(
- 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):
- if _config.get('HOOK_DEBUG', False):
- print(commitid, relation)
- fixes_relation(commitid, relation, session,
- _config.get('APP_URL'))
- for issue in pagure.lib.link.get_relation(
- session,
- pagure.lib.git.get_repo_name(abspath),
- pagure.lib.git.get_username(abspath),
- pagure.lib.git.get_repo_namespace(abspath),
- line,
- 'relates'):
- if _config.get('HOOK_DEBUG', False):
- print(commitid, issue)
- relates_commit(commitid, issue, session, _config.get('APP_URL'))
- session.close()
- def relates_commit(commitid, issue, session, 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)
- user = os.environ.get(
- 'GL_USER', pagure.lib.git.get_author_email(commitid, abspath))
- try:
- pagure.lib.add_issue_comment(
- session,
- issue=issue,
- comment=comment,
- user=user,
- ticketfolder=_config['TICKETS_FOLDER'],
- )
- session.commit()
- except pagure.exceptions.PagureException as err:
- print(err)
- except SQLAlchemyError as err: # pragma: no cover
- session.rollback()
- _log.exception(err)
- def fixes_relation(commitid, relation, session, 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)
- user = os.environ.get(
- 'GL_USER', pagure.lib.git.get_author_email(commitid, abspath))
- try:
- if relation.isa == 'issue':
- pagure.lib.add_issue_comment(
- session,
- issue=relation,
- comment=comment,
- user=user,
- ticketfolder=_config['TICKETS_FOLDER'],
- )
- elif relation.isa == 'pull-request':
- pagure.lib.add_pull_request_comment(
- session,
- request=relation,
- commit=None,
- tree_id=None,
- filename=None,
- row=None,
- comment=comment,
- user=user,
- requestfolder=_config['REQUESTS_FOLDER'],
- )
- session.commit()
- except pagure.exceptions.PagureException as err:
- print(err)
- except SQLAlchemyError as err: # pragma: no cover
- session.rollback()
- _log.exception(err)
- try:
- if relation.isa == 'issue':
- pagure.lib.edit_issue(
- session,
- relation,
- ticketfolder=_config['TICKETS_FOLDER'],
- user=user,
- status='Closed', close_status='Fixed')
- elif relation.isa == 'pull-request':
- pagure.lib.close_pull_request(
- session,
- relation,
- requestfolder=_config['REQUESTS_FOLDER'],
- user=user,
- merged=True)
- session.commit()
- except pagure.exceptions.PagureException as err:
- print(err)
- except SQLAlchemyError as err: # pragma: no cover
- session.rollback()
- print('ERROR', err)
- _log.exception(err)
- def run_as_post_receive_hook():
- for line in sys.stdin:
- if _config.get('HOOK_DEBUG', False):
- print(line)
- (oldrev, newrev, refname) = line.strip().split(' ', 2)
- if _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 _config.get('HOOK_DEBUG', False):
- print('ns :', pagure.lib.git.get_repo_namespace(abspath))
- 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:])
|