Show More
@@ -29,7 +29,6 b' from pyramid.httpexceptions import (' | |||||
29 | from pyramid.view import view_config |
|
29 | from pyramid.view import view_config | |
30 | from pyramid.renderers import render |
|
30 | from pyramid.renderers import render | |
31 |
|
31 | |||
32 | from rhodecode import events |
|
|||
33 | from rhodecode.apps._base import RepoAppView, DataGridAppView |
|
32 | from rhodecode.apps._base import RepoAppView, DataGridAppView | |
34 |
|
33 | |||
35 | from rhodecode.lib import helpers as h, diffs, codeblocks, channelstream |
|
34 | from rhodecode.lib import helpers as h, diffs, codeblocks, channelstream | |
@@ -1231,6 +1230,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1231 |
|
1230 | |||
1232 | def _update_reviewers(self, pull_request, review_members, reviewer_rules): |
|
1231 | def _update_reviewers(self, pull_request, review_members, reviewer_rules): | |
1233 | _ = self.request.translate |
|
1232 | _ = self.request.translate | |
|
1233 | ||||
1234 | get_default_reviewers_data, validate_default_reviewers = \ |
|
1234 | get_default_reviewers_data, validate_default_reviewers = \ | |
1235 | PullRequestModel().get_reviewer_functions() |
|
1235 | PullRequestModel().get_reviewer_functions() | |
1236 |
|
1236 | |||
@@ -1241,11 +1241,19 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1241 | h.flash(e, category='error') |
|
1241 | h.flash(e, category='error') | |
1242 | return |
|
1242 | return | |
1243 |
|
1243 | |||
|
1244 | old_calculated_status = pull_request.calculated_review_status() | |||
1244 | PullRequestModel().update_reviewers( |
|
1245 | PullRequestModel().update_reviewers( | |
1245 | pull_request, reviewers, self._rhodecode_user) |
|
1246 | pull_request, reviewers, self._rhodecode_user) | |
1246 | h.flash(_('Pull request reviewers updated.'), category='success') |
|
1247 | h.flash(_('Pull request reviewers updated.'), category='success') | |
1247 | Session().commit() |
|
1248 | Session().commit() | |
1248 |
|
1249 | |||
|
1250 | # trigger status changed if change in reviewers changes the status | |||
|
1251 | calculated_status = pull_request.calculated_review_status() | |||
|
1252 | if old_calculated_status != calculated_status: | |||
|
1253 | PullRequestModel().trigger_pull_request_hook( | |||
|
1254 | pull_request, self._rhodecode_user, 'review_status_change', | |||
|
1255 | data={'status': calculated_status}) | |||
|
1256 | ||||
1249 | @LoginRequired() |
|
1257 | @LoginRequired() | |
1250 | @NotAnonymous() |
|
1258 | @NotAnonymous() | |
1251 | @HasRepoPermissionAnyDecorator( |
|
1259 | @HasRepoPermissionAnyDecorator( | |
@@ -1324,12 +1332,16 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1324 | log.debug('comment: forbidden because not allowed to close ' |
|
1332 | log.debug('comment: forbidden because not allowed to close ' | |
1325 | 'pull request %s', pull_request_id) |
|
1333 | 'pull request %s', pull_request_id) | |
1326 | raise HTTPForbidden() |
|
1334 | raise HTTPForbidden() | |
|
1335 | ||||
|
1336 | # This also triggers `review_status_change` | |||
1327 | comment, status = PullRequestModel().close_pull_request_with_comment( |
|
1337 | comment, status = PullRequestModel().close_pull_request_with_comment( | |
1328 | pull_request, self._rhodecode_user, self.db_repo, message=text, |
|
1338 | pull_request, self._rhodecode_user, self.db_repo, message=text, | |
1329 | auth_user=self._rhodecode_user) |
|
1339 | auth_user=self._rhodecode_user) | |
1330 | Session().flush() |
|
1340 | Session().flush() | |
1331 | events.trigger( |
|
1341 | ||
1332 |
|
|
1342 | PullRequestModel().trigger_pull_request_hook( | |
|
1343 | pull_request, self._rhodecode_user, 'comment', | |||
|
1344 | data={'comment': comment}) | |||
1333 |
|
1345 | |||
1334 | else: |
|
1346 | else: | |
1335 | # regular comment case, could be inline, or one with status. |
|
1347 | # regular comment case, could be inline, or one with status. | |
@@ -1379,15 +1391,17 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1379 | # loaded on comment |
|
1391 | # loaded on comment | |
1380 | Session().refresh(comment) |
|
1392 | Session().refresh(comment) | |
1381 |
|
1393 | |||
1382 |
|
|
1394 | PullRequestModel().trigger_pull_request_hook( | |
1383 | events.PullRequestCommentEvent(pull_request, comment)) |
|
1395 | pull_request, self._rhodecode_user, 'comment', | |
|
1396 | data={'comment': comment}) | |||
1384 |
|
1397 | |||
1385 | # we now calculate the status of pull request, and based on that |
|
1398 | # we now calculate the status of pull request, and based on that | |
1386 | # calculation we set the commits status |
|
1399 | # calculation we set the commits status | |
1387 | calculated_status = pull_request.calculated_review_status() |
|
1400 | calculated_status = pull_request.calculated_review_status() | |
1388 | if old_calculated_status != calculated_status: |
|
1401 | if old_calculated_status != calculated_status: | |
1389 |
PullRequestModel(). |
|
1402 | PullRequestModel().trigger_pull_request_hook( | |
1390 |
pull_request, self._rhodecode_user, 'review_status_change' |
|
1403 | pull_request, self._rhodecode_user, 'review_status_change', | |
|
1404 | data={'status': calculated_status}) | |||
1391 |
|
1405 | |||
1392 | Session().commit() |
|
1406 | Session().commit() | |
1393 |
|
1407 | |||
@@ -1447,8 +1461,9 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1447 | Session().commit() |
|
1461 | Session().commit() | |
1448 | calculated_status = comment.pull_request.calculated_review_status() |
|
1462 | calculated_status = comment.pull_request.calculated_review_status() | |
1449 | if old_calculated_status != calculated_status: |
|
1463 | if old_calculated_status != calculated_status: | |
1450 |
PullRequestModel(). |
|
1464 | PullRequestModel().trigger_pull_request_hook( | |
1451 |
comment.pull_request, self._rhodecode_user, 'review_status_change' |
|
1465 | comment.pull_request, self._rhodecode_user, 'review_status_change', | |
|
1466 | data={'status': calculated_status}) | |||
1452 | return True |
|
1467 | return True | |
1453 | else: |
|
1468 | else: | |
1454 | log.warning('No permissions for user %s to delete comment_id: %s', |
|
1469 | log.warning('No permissions for user %s to delete comment_id: %s', |
@@ -100,11 +100,15 b' class PullRequestUpdateEvent(PullRequest' | |||||
100 | class PullRequestReviewEvent(PullRequestEvent): |
|
100 | class PullRequestReviewEvent(PullRequestEvent): | |
101 | """ |
|
101 | """ | |
102 | An instance of this class is emitted as an :term:`event` after a pull |
|
102 | An instance of this class is emitted as an :term:`event` after a pull | |
103 | request review has changed. |
|
103 | request review has changed. A status defines new status of review. | |
104 | """ |
|
104 | """ | |
105 | name = 'pullrequest-review' |
|
105 | name = 'pullrequest-review' | |
106 | display_name = lazy_ugettext('pullrequest review changed') |
|
106 | display_name = lazy_ugettext('pullrequest review changed') | |
107 |
|
107 | |||
|
108 | def __init__(self, pullrequest, status): | |||
|
109 | super(PullRequestReviewEvent, self).__init__(pullrequest) | |||
|
110 | self.status = status | |||
|
111 | ||||
108 |
|
112 | |||
109 | class PullRequestMergeEvent(PullRequestEvent): |
|
113 | class PullRequestMergeEvent(PullRequestEvent): | |
110 | """ |
|
114 | """ |
@@ -64,7 +64,7 b' def trigger_post_push_hook(' | |||||
64 |
|
64 | |||
65 |
|
65 | |||
66 | def trigger_log_create_pull_request_hook(username, repo_name, repo_alias, |
|
66 | def trigger_log_create_pull_request_hook(username, repo_name, repo_alias, | |
67 | pull_request): |
|
67 | pull_request, data=None): | |
68 | """ |
|
68 | """ | |
69 | Triggers create pull request action hooks |
|
69 | Triggers create pull request action hooks | |
70 |
|
70 | |||
@@ -72,6 +72,7 b' def trigger_log_create_pull_request_hook' | |||||
72 | :param repo_name: name of target repo |
|
72 | :param repo_name: name of target repo | |
73 | :param repo_alias: the type of SCM target repo |
|
73 | :param repo_alias: the type of SCM target repo | |
74 | :param pull_request: the pull request that was created |
|
74 | :param pull_request: the pull request that was created | |
|
75 | :param data: extra data for specific events e.g {'comment': comment_obj} | |||
75 | """ |
|
76 | """ | |
76 | if repo_alias not in ('hg', 'git'): |
|
77 | if repo_alias not in ('hg', 'git'): | |
77 | return |
|
78 | return | |
@@ -84,7 +85,7 b' def trigger_log_create_pull_request_hook' | |||||
84 |
|
85 | |||
85 |
|
86 | |||
86 | def trigger_log_merge_pull_request_hook(username, repo_name, repo_alias, |
|
87 | def trigger_log_merge_pull_request_hook(username, repo_name, repo_alias, | |
87 | pull_request): |
|
88 | pull_request, data=None): | |
88 | """ |
|
89 | """ | |
89 | Triggers merge pull request action hooks |
|
90 | Triggers merge pull request action hooks | |
90 |
|
91 | |||
@@ -92,6 +93,7 b' def trigger_log_merge_pull_request_hook(' | |||||
92 | :param repo_name: name of target repo |
|
93 | :param repo_name: name of target repo | |
93 | :param repo_alias: the type of SCM target repo |
|
94 | :param repo_alias: the type of SCM target repo | |
94 | :param pull_request: the pull request that was merged |
|
95 | :param pull_request: the pull request that was merged | |
|
96 | :param data: extra data for specific events e.g {'comment': comment_obj} | |||
95 | """ |
|
97 | """ | |
96 | if repo_alias not in ('hg', 'git'): |
|
98 | if repo_alias not in ('hg', 'git'): | |
97 | return |
|
99 | return | |
@@ -104,7 +106,7 b' def trigger_log_merge_pull_request_hook(' | |||||
104 |
|
106 | |||
105 |
|
107 | |||
106 | def trigger_log_close_pull_request_hook(username, repo_name, repo_alias, |
|
108 | def trigger_log_close_pull_request_hook(username, repo_name, repo_alias, | |
107 | pull_request): |
|
109 | pull_request, data=None): | |
108 | """ |
|
110 | """ | |
109 | Triggers close pull request action hooks |
|
111 | Triggers close pull request action hooks | |
110 |
|
112 | |||
@@ -112,6 +114,7 b' def trigger_log_close_pull_request_hook(' | |||||
112 | :param repo_name: name of target repo |
|
114 | :param repo_name: name of target repo | |
113 | :param repo_alias: the type of SCM target repo |
|
115 | :param repo_alias: the type of SCM target repo | |
114 | :param pull_request: the pull request that was closed |
|
116 | :param pull_request: the pull request that was closed | |
|
117 | :param data: extra data for specific events e.g {'comment': comment_obj} | |||
115 | """ |
|
118 | """ | |
116 | if repo_alias not in ('hg', 'git'): |
|
119 | if repo_alias not in ('hg', 'git'): | |
117 | return |
|
120 | return | |
@@ -124,7 +127,7 b' def trigger_log_close_pull_request_hook(' | |||||
124 |
|
127 | |||
125 |
|
128 | |||
126 | def trigger_log_review_pull_request_hook(username, repo_name, repo_alias, |
|
129 | def trigger_log_review_pull_request_hook(username, repo_name, repo_alias, | |
127 | pull_request): |
|
130 | pull_request, data=None): | |
128 | """ |
|
131 | """ | |
129 | Triggers review status change pull request action hooks |
|
132 | Triggers review status change pull request action hooks | |
130 |
|
133 | |||
@@ -132,19 +135,21 b' def trigger_log_review_pull_request_hook' | |||||
132 | :param repo_name: name of target repo |
|
135 | :param repo_name: name of target repo | |
133 | :param repo_alias: the type of SCM target repo |
|
136 | :param repo_alias: the type of SCM target repo | |
134 | :param pull_request: the pull request that review status changed |
|
137 | :param pull_request: the pull request that review status changed | |
|
138 | :param data: extra data for specific events e.g {'comment': comment_obj} | |||
135 | """ |
|
139 | """ | |
136 | if repo_alias not in ('hg', 'git'): |
|
140 | if repo_alias not in ('hg', 'git'): | |
137 | return |
|
141 | return | |
138 |
|
142 | |||
139 | extras = _get_rc_scm_extras(username, repo_name, repo_alias, |
|
143 | extras = _get_rc_scm_extras(username, repo_name, repo_alias, | |
140 | 'review_pull_request') |
|
144 | 'review_pull_request') | |
141 | events.trigger(events.PullRequestReviewEvent(pull_request)) |
|
145 | status = data.get('status') | |
|
146 | events.trigger(events.PullRequestReviewEvent(pull_request, status)) | |||
142 | extras.update(pull_request.get_api_data()) |
|
147 | extras.update(pull_request.get_api_data()) | |
143 | hooks_base.log_review_pull_request(**extras) |
|
148 | hooks_base.log_review_pull_request(**extras) | |
144 |
|
149 | |||
145 |
|
150 | |||
146 | def trigger_log_update_pull_request_hook(username, repo_name, repo_alias, |
|
151 | def trigger_log_update_pull_request_hook(username, repo_name, repo_alias, | |
147 | pull_request): |
|
152 | pull_request, data=None): | |
148 | """ |
|
153 | """ | |
149 | Triggers update pull request action hooks |
|
154 | Triggers update pull request action hooks | |
150 |
|
155 | |||
@@ -152,6 +157,7 b' def trigger_log_update_pull_request_hook' | |||||
152 | :param repo_name: name of target repo |
|
157 | :param repo_name: name of target repo | |
153 | :param repo_alias: the type of SCM target repo |
|
158 | :param repo_alias: the type of SCM target repo | |
154 | :param pull_request: the pull request that was updated |
|
159 | :param pull_request: the pull request that was updated | |
|
160 | :param data: extra data for specific events e.g {'comment': comment_obj} | |||
155 | """ |
|
161 | """ | |
156 | if repo_alias not in ('hg', 'git'): |
|
162 | if repo_alias not in ('hg', 'git'): | |
157 | return |
|
163 | return |
@@ -513,7 +513,7 b' class PullRequestModel(BaseModel):' | |||||
513 | pull_request, auth_user=auth_user, translator=translator) |
|
513 | pull_request, auth_user=auth_user, translator=translator) | |
514 |
|
514 | |||
515 | self.notify_reviewers(pull_request, reviewer_ids) |
|
515 | self.notify_reviewers(pull_request, reviewer_ids) | |
516 |
self. |
|
516 | self.trigger_pull_request_hook( | |
517 | pull_request, created_by_user, 'create') |
|
517 | pull_request, created_by_user, 'create') | |
518 |
|
518 | |||
519 | creation_data = pull_request.get_api_data(with_merge_state=False) |
|
519 | creation_data = pull_request.get_api_data(with_merge_state=False) | |
@@ -523,7 +523,7 b' class PullRequestModel(BaseModel):' | |||||
523 |
|
523 | |||
524 | return pull_request |
|
524 | return pull_request | |
525 |
|
525 | |||
526 |
def |
|
526 | def trigger_pull_request_hook(self, pull_request, user, action, data=None): | |
527 | pull_request = self.__get_pull_request(pull_request) |
|
527 | pull_request = self.__get_pull_request(pull_request) | |
528 | target_scm = pull_request.target_repo.scm_instance() |
|
528 | target_scm = pull_request.target_repo.scm_instance() | |
529 | if action == 'create': |
|
529 | if action == 'create': | |
@@ -536,6 +536,12 b' class PullRequestModel(BaseModel):' | |||||
536 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook |
|
536 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook | |
537 | elif action == 'update': |
|
537 | elif action == 'update': | |
538 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook |
|
538 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook | |
|
539 | elif action == 'comment': | |||
|
540 | # dummy hook ! for comment. We want this function to handle all cases | |||
|
541 | def trigger_hook(*args, **kwargs): | |||
|
542 | pass | |||
|
543 | comment = data['comment'] | |||
|
544 | events.trigger(events.PullRequestCommentEvent(pull_request, comment)) | |||
539 | else: |
|
545 | else: | |
540 | return |
|
546 | return | |
541 |
|
547 | |||
@@ -543,7 +549,8 b' class PullRequestModel(BaseModel):' | |||||
543 | username=user.username, |
|
549 | username=user.username, | |
544 | repo_name=pull_request.target_repo.repo_name, |
|
550 | repo_name=pull_request.target_repo.repo_name, | |
545 | repo_alias=target_scm.alias, |
|
551 | repo_alias=target_scm.alias, | |
546 |
pull_request=pull_request |
|
552 | pull_request=pull_request, | |
|
553 | data=data) | |||
547 |
|
554 | |||
548 | def _get_commit_ids(self, pull_request): |
|
555 | def _get_commit_ids(self, pull_request): | |
549 | """ |
|
556 | """ | |
@@ -642,7 +649,7 b' class PullRequestModel(BaseModel):' | |||||
642 | # TODO: paris: replace invalidation with less radical solution |
|
649 | # TODO: paris: replace invalidation with less radical solution | |
643 | ScmModel().mark_for_invalidation( |
|
650 | ScmModel().mark_for_invalidation( | |
644 | pull_request.target_repo.repo_name) |
|
651 | pull_request.target_repo.repo_name) | |
645 |
self. |
|
652 | self.trigger_pull_request_hook(pull_request, user, 'merge') | |
646 |
|
653 | |||
647 | def has_valid_update_type(self, pull_request): |
|
654 | def has_valid_update_type(self, pull_request): | |
648 | source_ref_type = pull_request.source_ref_parts.type |
|
655 | source_ref_type = pull_request.source_ref_parts.type | |
@@ -811,7 +818,7 b' class PullRequestModel(BaseModel):' | |||||
811 | pull_request.source_ref_parts.commit_id, |
|
818 | pull_request.source_ref_parts.commit_id, | |
812 | pull_request_version.pull_request_version_id) |
|
819 | pull_request_version.pull_request_version_id) | |
813 | Session().commit() |
|
820 | Session().commit() | |
814 |
self. |
|
821 | self.trigger_pull_request_hook(pull_request, pull_request.author, 'update') | |
815 |
|
822 | |||
816 | return UpdateResponse( |
|
823 | return UpdateResponse( | |
817 | executed=True, reason=UpdateFailureReason.NONE, |
|
824 | executed=True, reason=UpdateFailureReason.NONE, | |
@@ -1146,7 +1153,7 b' class PullRequestModel(BaseModel):' | |||||
1146 | pull_request.status = PullRequest.STATUS_CLOSED |
|
1153 | pull_request.status = PullRequest.STATUS_CLOSED | |
1147 | pull_request.updated_on = datetime.datetime.now() |
|
1154 | pull_request.updated_on = datetime.datetime.now() | |
1148 | Session().add(pull_request) |
|
1155 | Session().add(pull_request) | |
1149 |
self. |
|
1156 | self.trigger_pull_request_hook( | |
1150 | pull_request, pull_request.author, 'close') |
|
1157 | pull_request, pull_request.author, 'close') | |
1151 |
|
1158 | |||
1152 | pr_data = pull_request.get_api_data(with_merge_state=False) |
|
1159 | pr_data = pull_request.get_api_data(with_merge_state=False) | |
@@ -1200,8 +1207,9 b' class PullRequestModel(BaseModel):' | |||||
1200 | # change the status, while if he's a reviewer this might change it. |
|
1207 | # change the status, while if he's a reviewer this might change it. | |
1201 | calculated_status = pull_request.calculated_review_status() |
|
1208 | calculated_status = pull_request.calculated_review_status() | |
1202 | if old_calculated_status != calculated_status: |
|
1209 | if old_calculated_status != calculated_status: | |
1203 |
self. |
|
1210 | self.trigger_pull_request_hook( | |
1204 |
pull_request, user, 'review_status_change' |
|
1211 | pull_request, user, 'review_status_change', | |
|
1212 | data={'status': calculated_status}) | |||
1205 |
|
1213 | |||
1206 | # finally close the PR |
|
1214 | # finally close the PR | |
1207 | PullRequestModel().close_pull_request( |
|
1215 | PullRequestModel().close_pull_request( |
@@ -71,7 +71,7 b' class TestPullRequestModel(object):' | |||||
71 | self.helper_patcher.start() |
|
71 | self.helper_patcher.start() | |
72 |
|
72 | |||
73 | self.hook_patcher = mock.patch.object(PullRequestModel, |
|
73 | self.hook_patcher = mock.patch.object(PullRequestModel, | |
74 |
' |
|
74 | 'trigger_pull_request_hook') | |
75 | self.hook_mock = self.hook_patcher.start() |
|
75 | self.hook_mock = self.hook_patcher.start() | |
76 |
|
76 | |||
77 | self.invalidation_patcher = mock.patch( |
|
77 | self.invalidation_patcher = mock.patch( |
General Comments 0
You need to be logged in to leave comments.
Login now