diff --git a/progit/hooks/files/progit_hook.py b/progit/hooks/files/progit_hook.py index 7644f9d..8d01132 100644 --- a/progit/hooks/files/progit_hook.py +++ b/progit/hooks/files/progit_hook.py @@ -21,24 +21,6 @@ import progit import progit.exceptions -# TODO: Move this to progit.lib so that it can also be used in comments -# in tickets or pull-requests -FIXES = [ - re.compile('fixe?[sd]?:?\s?#(\d+)', re.I), - re.compile('.*\s+fixe?[sd]?:?\s?#(\d+)', re.I), - re.compile('fixe?[sd]?:?\s?https?://.*/(\w+)/issue/(\d+)', re.I), - re.compile('.*\s+fixe?[sd]?:?\s?https?://.*/(\w+)/issue/(\d+)', re.I), -] - -RELATES = [ - re.compile('relate[sd]?:?\s?(?:to)?\s?#(\d+)', re.I), - re.compile('.*\s+relate[sd]?:?\s?#(\d+)', re.I), - re.compile( - 'relate[sd]?:?\s?(?:to)?\s?https?://.*/(\w+)/issue/(\d+)', re.I), - re.compile('.*\s+relate[sd]?:?\s?(?:to)?\s?https?://.*/(\w+)/issue/(\d+)', re.I), -] - - def read_git_output(args, input=None, keepends=False, **kw): """Read the output of a Git command.""" @@ -85,42 +67,19 @@ def generate_revision_change_log(new_commits_list): line = line.strip() print '*', line - for motif in FIXES: - if motif.match(line): - print 'fixes', motif.match(line).groups() - project = None - if len(motif.match(line).groups()) >= 2: - issueid = motif.match(line).group(2) - project = motif.match(line).group(1) - else: - issueid = motif.match(line).group(1) - fixes_commit(commitid, issueid, project) - for motif in RELATES: - if motif.match(line): - print 'relates to', motif.match(line).groups() - project = None - if len(motif.match(line).groups()) >= 2: - issueid = motif.match(line).group(2) - project = motif.match(line).group(1) - else: - issueid = motif.match(line).group(1) - relates_commit(commitid, issueid, project) - - -def relates_commit(commitid, issueid, project=None): - ''' Add a comment to an issue that this commit relates to it. ''' - repo = project or get_repo_name() - username = get_username() + for issue in progit.lib.link.get_relation( + progit.SESSION, get_repo_name(), get_username(), + line, 'fixes') + fixes_commit(commitid, issue, project) - repo = progit.lib.get_project(progit.SESSION, repo, user=username) - if not repo: - repo = progit.lib.get_project( - progit.SESSION, get_repo_name(), user=username) - issue = progit.lib.search_issues( - progit.SESSION, repo=repo, issueid=issueid) + for issue in progit.lib.link.get_relates_link( + progit.SESSION, get_repo_name(), get_username(), + line, 'relates') + relates_commit(commitid, issue, project) - if issue is None or issue.project != repo: - return + +def relates_commit(commitid, issue, project=None): + ''' Add a comment to an issue that this commit relates to it. ''' comment = ''' Commit [%s](../%s) relates to this ticket''' % ( commitid[:8], commitid[:8]) @@ -141,21 +100,9 @@ def relates_commit(commitid, issueid, project=None): progit.APP.logger.exception(err) -def fixes_commit(commitid, issueid, project=None): +def fixes_commit(commitid, issue, project=None): ''' Add a comment to an issue that this commit fixes it and update the status if the commit is in the master branch. ''' - repo = project or get_repo_name() - username = get_username() - - repo = progit.lib.get_project(progit.SESSION, repo, user=username) - if not repo: - repo = progit.lib.get_project( - progit.SESSION, get_repo_name(), user=username) - issue = progit.lib.search_issues( - progit.SESSION, repo, issueid=issueid) - - if issue is None or issue.project != repo: - return comment = ''' Commit [%s](../%s) fixes this ticket''' % ( commitid[:8], commitid[:8]) diff --git a/progit/lib/link.py b/progit/lib/link.py new file mode 100644 index 0000000..f209f16 --- /dev/null +++ b/progit/lib/link.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +""" + (c) 2015 - Copyright Red Hat Inc + + Authors: + Pierre-Yves Chibon + +""" + + +import re +import os + +import progit.exceptions + + +FIXES = [ + re.compile('fixe?[sd]?:?\s?#(\d+)', re.I), + re.compile('.*\s+fixe?[sd]?:?\s?#(\d+)', re.I), + re.compile('fixe?[sd]?:?\s?https?://.*/(\w+)/issue/(\d+)', re.I), + re.compile('.*\s+fixe?[sd]?:?\s?https?://.*/(\w+)/issue/(\d+)', re.I), +] + +RELATES = [ + re.compile('.*\s+relate[sd]?:?\s?(?:to)?\s?#(\d+)', re.I), + re.compile('.*\s+relate[sd]?:?\s?#(\d+)', re.I), + re.compile( + '.*\s+relate[sd]?:?\s?(?:to)?\s?https?://.*/(\w+)/issue/(\d+)', re.I), + re.compile('.*\s+relate[sd]?:?\s?(?:to)?\s?https?://.*/(\w+)/issue/(\d+)', re.I), +] + + +def get_relation(session, reponame, username, text, reftype='relates'): + ''' For a given text, searches using regex if the text contains + reference to another issue in this project or another one. + + Returns the list of issues referenced (possibly empty). + + By default it searches for references of type: `relates`, for example: + ``this commits relates to #2``. + Another reference type is: `fixes` refering to text including for + example: ``this commits fixes #3``. + + + ''' + + repo = progit.lib.get_project(session, reponame, user=username) + if not repo: + return [] + + regex = RELATES + if reftype == 'fixes': + regex = FIXES + + issues = [] + for motif in regex: + issueid = None + project = None + print text, motif + print motif.match(text) + if motif.match(text): + print 'references', motif.match(text).groups() + if len(motif.match(text).groups()) >= 2: + issueid = motif.match(text).group(2) + project = motif.match(text).group(1) + else: + issueid = motif.match(text).group(1) + + if issueid: + issue = progit.lib.search_issues( + session, repo=repo, issueid=issueid) + if issue is None or issue.project.name not in [project, repo.name]: + continue + + print issueid, project, repo.name + issues.append(issue) + + return issues