events: add an event for pull request comments with review status

This commit is contained in:
Daniel Dourvaris 2016-07-13 10:39:54 +02:00
parent 990143eae0
commit 88e83cf796
6 changed files with 123 additions and 17 deletions

View file

@ -32,6 +32,7 @@ from pylons.i18n.translation import _
from sqlalchemy.sql import func
from sqlalchemy.sql.expression import or_
from rhodecode import events
from rhodecode.lib import auth, diffs, helpers as h
from rhodecode.lib.ext_json import json
from rhodecode.lib.base import (
@ -764,6 +765,8 @@ class PullrequestsController(BaseRepoController):
closing_pr=close_pr
)
if allowed_to_change_status:
old_calculated_status = pull_request.calculated_review_status()
# get status if set !
@ -777,6 +780,7 @@ class PullrequestsController(BaseRepoController):
)
Session().flush()
events.trigger(events.PullRequestCommentEvent(pull_request, comm))
# we now calculate the status of pull request, and based on that
# calculation we set the commits status
calculated_status = pull_request.calculated_review_status()

View file

@ -64,6 +64,7 @@ from rhodecode.events.pullrequest import (
PullRequestEvent,
PullRequestCreateEvent,
PullRequestUpdateEvent,
PullRequestCommentEvent,
PullRequestReviewEvent,
PullRequestMergeEvent,
PullRequestCloseEvent,

View file

@ -44,7 +44,8 @@ class PullRequestEvent(RepoEvent):
'title': self.pullrequest.title,
'issues': issues,
'pull_request_id': self.pullrequest.pull_request_id,
'url': PullRequestModel().get_url(self.pullrequest)
'url': PullRequestModel().get_url(self.pullrequest),
'status': self.pullrequest.calculated_review_status(),
}
})
return data
@ -71,10 +72,19 @@ class PullRequestCloseEvent(PullRequestEvent):
class PullRequestUpdateEvent(PullRequestEvent):
"""
An instance of this class is emitted as an :term:`event` after a pull
request is updated.
request's commits have been updated.
"""
name = 'pullrequest-update'
display_name = lazy_ugettext('pullrequest updated')
display_name = lazy_ugettext('pullrequest commits updated')
class PullRequestReviewEvent(PullRequestEvent):
"""
An instance of this class is emitted as an :term:`event` after a pull
request review has changed.
"""
name = 'pullrequest-review'
display_name = lazy_ugettext('pullrequest review changed')
class PullRequestMergeEvent(PullRequestEvent):
@ -86,12 +96,31 @@ class PullRequestMergeEvent(PullRequestEvent):
display_name = lazy_ugettext('pullrequest merged')
class PullRequestReviewEvent(PullRequestEvent):
class PullRequestCommentEvent(PullRequestEvent):
"""
An instance of this class is emitted as an :term:`event` after a pull
request is reviewed.
request comment is created.
"""
name = 'pullrequest-review'
display_name = lazy_ugettext('pullrequest reviewed')
name = 'pullrequest-comment'
display_name = lazy_ugettext('pullrequest commented')
def __init__(self, pullrequest, comment):
super(PullRequestCommentEvent, self).__init__(pullrequest)
self.comment = comment
def as_dict(self):
from rhodecode.model.comment import ChangesetCommentsModel
data = super(PullRequestCommentEvent, self).as_dict()
status = None
if self.comment.status_change:
status = self.comment.status_change[0].status
data.update({
'comment': {
'status': status,
'text': self.comment.text,
'url': ChangesetCommentsModel().get_url(self.comment)
}
})
return data

View file

@ -24,6 +24,7 @@ import re
import logging
import requests
import colander
import textwrap
from celery.task import task
from mako.template import Template
@ -105,6 +106,7 @@ class SlackIntegrationType(IntegrationTypeBase):
events.PullRequestCloseEvent,
events.PullRequestMergeEvent,
events.PullRequestUpdateEvent,
events.PullRequestCommentEvent,
events.PullRequestReviewEvent,
events.PullRequestCreateEvent,
events.RepoPushEvent,
@ -127,7 +129,11 @@ class SlackIntegrationType(IntegrationTypeBase):
log.debug('handling slack event for %s' % event.name)
if isinstance(event, events.PullRequestEvent):
if isinstance(event, events.PullRequestCommentEvent):
text = self.format_pull_request_comment_event(event, data)
elif isinstance(event, events.PullRequestReviewEvent):
text = self.format_pull_request_review_event(event, data)
elif isinstance(event, events.PullRequestEvent):
text = self.format_pull_request_event(event, data)
elif isinstance(event, events.RepoPushEvent):
text = self.format_repo_push_event(data)
@ -150,16 +156,55 @@ class SlackIntegrationType(IntegrationTypeBase):
))
return schema
def format_pull_request_comment_event(self, event, data):
comment_text = data['comment']['text']
if len(comment_text) > 200:
comment_text = '<{comment_url}|{comment_text}...>'.format(
comment_text=comment_text[:200],
comment_url=data['comment']['url'],
)
comment_status = ''
if data['comment']['status']:
comment_status = '[{}]: '.format(data['comment']['status'])
return (textwrap.dedent(
'''
{user} commented on pull request <{pr_url}|#{number}> - {pr_title}:
>>> {comment_status}{comment_text}
''').format(
comment_status=comment_status,
user=data['actor']['username'],
number=data['pullrequest']['pull_request_id'],
pr_url=data['pullrequest']['url'],
pr_status=data['pullrequest']['status'],
pr_title=data['pullrequest']['title'],
comment_text=comment_text
)
)
def format_pull_request_review_event(self, event, data):
return (textwrap.dedent(
'''
Status changed to {pr_status} for pull request <{pr_url}|#{number}> - {pr_title}
''').format(
user=data['actor']['username'],
number=data['pullrequest']['pull_request_id'],
pr_url=data['pullrequest']['url'],
pr_status=data['pullrequest']['status'],
pr_title=data['pullrequest']['title'],
)
)
def format_pull_request_event(self, event, data):
action = {
events.PullRequestCloseEvent: 'closed',
events.PullRequestMergeEvent: 'merged',
events.PullRequestUpdateEvent: 'updated',
events.PullRequestReviewEvent: 'reviewed',
events.PullRequestCreateEvent: 'created',
}.get(event.__class__, '<unknown action>')
}.get(event.__class__, str(event.__class__))
return ('Pull request <{url}|#{number}> ({title}) '
return ('Pull request <{url}|#{number}> - {title} '
'{action} by {user}').format(
user=data['actor']['username'],
number=data['pullrequest']['pull_request_id'],

View file

@ -156,12 +156,7 @@ class ChangesetCommentsModel(BaseModel):
cs_author = repo.user
recipients += [cs_author]
commit_comment_url = h.url(
'changeset_home',
repo_name=repo.repo_name,
revision=commit_obj.raw_id,
anchor='comment-%s' % comment.comment_id,
qualified=True,)
commit_comment_url = self.get_url(comment)
target_repo_url = h.link_to(
repo.repo_name,
@ -271,6 +266,23 @@ class ChangesetCommentsModel(BaseModel):
q = q.order_by(ChangesetComment.created_on)
return q.all()
def get_url(self, comment):
comment = self.__get_commit_comment(comment)
if comment.pull_request:
return h.url(
'pullrequest_show',
repo_name=comment.pull_request.target_repo.repo_name,
pull_request_id=comment.pull_request.pull_request_id,
anchor='comment-%s' % comment.comment_id,
qualified=True,)
else:
return h.url(
'changeset_home',
repo_name=comment.repo.repo_name,
revision=comment.revision,
anchor='comment-%s' % comment.comment_id,
qualified=True,)
def get_comments(self, repo_id, revision=None, pull_request=None):
"""
Gets main comments based on revision or pull_request_id

View file

@ -22,10 +22,12 @@ import pytest
from rhodecode.tests.events.conftest import EventCatcher
from rhodecode.model.comment import ChangesetCommentsModel
from rhodecode.model.pull_request import PullRequestModel
from rhodecode.events import (
PullRequestCreateEvent,
PullRequestUpdateEvent,
PullRequestCommentEvent,
PullRequestReviewEvent,
PullRequestMergeEvent,
PullRequestCloseEvent,
@ -56,6 +58,19 @@ def test_create_pull_request_events(pr_util):
assert PullRequestCreateEvent in event_catcher.events_types
@pytest.mark.backends("git", "hg")
def test_pullrequest_comment_events_serialized(pr_util):
pr = pr_util.create_pull_request()
comment = ChangesetCommentsModel().get_comments(
pr.target_repo.repo_id, pull_request=pr)[0]
event = PullRequestCommentEvent(pr, comment)
data = event.as_dict()
assert data['name'] == PullRequestCommentEvent.name
assert data['repo']['repo_name'] == pr.target_repo.repo_name
assert data['pullrequest']['pull_request_id'] == pr.pull_request_id
assert data['pullrequest']['url']
assert data['comment']['text'] == comment.text
@pytest.mark.backends("git", "hg")
def test_close_pull_request_events(pr_util, user_admin):