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 | |
@@ -1176,6 +1175,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1176 |
|
1175 | |||
1177 | def _update_reviewers(self, pull_request, review_members, reviewer_rules): |
|
1176 | def _update_reviewers(self, pull_request, review_members, reviewer_rules): | |
1178 | _ = self.request.translate |
|
1177 | _ = self.request.translate | |
|
1178 | ||||
1179 | get_default_reviewers_data, validate_default_reviewers = \ |
|
1179 | get_default_reviewers_data, validate_default_reviewers = \ | |
1180 | PullRequestModel().get_reviewer_functions() |
|
1180 | PullRequestModel().get_reviewer_functions() | |
1181 |
|
1181 | |||
@@ -1186,11 +1186,19 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1186 | h.flash(e, category='error') |
|
1186 | h.flash(e, category='error') | |
1187 | return |
|
1187 | return | |
1188 |
|
1188 | |||
|
1189 | old_calculated_status = pull_request.calculated_review_status() | |||
1189 | PullRequestModel().update_reviewers( |
|
1190 | PullRequestModel().update_reviewers( | |
1190 | pull_request, reviewers, self._rhodecode_user) |
|
1191 | pull_request, reviewers, self._rhodecode_user) | |
1191 | h.flash(_('Pull request reviewers updated.'), category='success') |
|
1192 | h.flash(_('Pull request reviewers updated.'), category='success') | |
1192 | Session().commit() |
|
1193 | Session().commit() | |
1193 |
|
1194 | |||
|
1195 | # trigger status changed if change in reviewers changes the status | |||
|
1196 | calculated_status = pull_request.calculated_review_status() | |||
|
1197 | if old_calculated_status != calculated_status: | |||
|
1198 | PullRequestModel().trigger_pull_request_hook( | |||
|
1199 | pull_request, self._rhodecode_user, 'review_status_change', | |||
|
1200 | data={'status': calculated_status}) | |||
|
1201 | ||||
1194 | @LoginRequired() |
|
1202 | @LoginRequired() | |
1195 | @NotAnonymous() |
|
1203 | @NotAnonymous() | |
1196 | @HasRepoPermissionAnyDecorator( |
|
1204 | @HasRepoPermissionAnyDecorator( | |
@@ -1269,12 +1277,16 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1269 | log.debug('comment: forbidden because not allowed to close ' |
|
1277 | log.debug('comment: forbidden because not allowed to close ' | |
1270 | 'pull request %s', pull_request_id) |
|
1278 | 'pull request %s', pull_request_id) | |
1271 | raise HTTPForbidden() |
|
1279 | raise HTTPForbidden() | |
|
1280 | ||||
|
1281 | # This also triggers `review_status_change` | |||
1272 | comment, status = PullRequestModel().close_pull_request_with_comment( |
|
1282 | comment, status = PullRequestModel().close_pull_request_with_comment( | |
1273 | pull_request, self._rhodecode_user, self.db_repo, message=text, |
|
1283 | pull_request, self._rhodecode_user, self.db_repo, message=text, | |
1274 | auth_user=self._rhodecode_user) |
|
1284 | auth_user=self._rhodecode_user) | |
1275 | Session().flush() |
|
1285 | Session().flush() | |
1276 | events.trigger( |
|
1286 | ||
1277 |
|
|
1287 | PullRequestModel().trigger_pull_request_hook( | |
|
1288 | pull_request, self._rhodecode_user, 'comment', | |||
|
1289 | data={'comment': comment}) | |||
1278 |
|
1290 | |||
1279 | else: |
|
1291 | else: | |
1280 | # regular comment case, could be inline, or one with status. |
|
1292 | # regular comment case, could be inline, or one with status. | |
@@ -1324,15 +1336,17 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1324 | # loaded on comment |
|
1336 | # loaded on comment | |
1325 | Session().refresh(comment) |
|
1337 | Session().refresh(comment) | |
1326 |
|
1338 | |||
1327 |
|
|
1339 | PullRequestModel().trigger_pull_request_hook( | |
1328 | events.PullRequestCommentEvent(pull_request, comment)) |
|
1340 | pull_request, self._rhodecode_user, 'comment', | |
|
1341 | data={'comment': comment}) | |||
1329 |
|
1342 | |||
1330 | # we now calculate the status of pull request, and based on that |
|
1343 | # we now calculate the status of pull request, and based on that | |
1331 | # calculation we set the commits status |
|
1344 | # calculation we set the commits status | |
1332 | calculated_status = pull_request.calculated_review_status() |
|
1345 | calculated_status = pull_request.calculated_review_status() | |
1333 | if old_calculated_status != calculated_status: |
|
1346 | if old_calculated_status != calculated_status: | |
1334 |
PullRequestModel(). |
|
1347 | PullRequestModel().trigger_pull_request_hook( | |
1335 |
pull_request, self._rhodecode_user, 'review_status_change' |
|
1348 | pull_request, self._rhodecode_user, 'review_status_change', | |
|
1349 | data={'status': calculated_status}) | |||
1336 |
|
1350 | |||
1337 | Session().commit() |
|
1351 | Session().commit() | |
1338 |
|
1352 | |||
@@ -1392,8 +1406,9 b' class RepoPullRequestsView(RepoAppView, ' | |||||
1392 | Session().commit() |
|
1406 | Session().commit() | |
1393 | calculated_status = comment.pull_request.calculated_review_status() |
|
1407 | calculated_status = comment.pull_request.calculated_review_status() | |
1394 | if old_calculated_status != calculated_status: |
|
1408 | if old_calculated_status != calculated_status: | |
1395 |
PullRequestModel(). |
|
1409 | PullRequestModel().trigger_pull_request_hook( | |
1396 |
comment.pull_request, self._rhodecode_user, 'review_status_change' |
|
1410 | comment.pull_request, self._rhodecode_user, 'review_status_change', | |
|
1411 | data={'status': calculated_status}) | |||
1397 | return True |
|
1412 | return True | |
1398 | else: |
|
1413 | else: | |
1399 | log.warning('No permissions for user %s to delete comment_id: %s', |
|
1414 | 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 |
@@ -539,7 +539,7 b' class PullRequestModel(BaseModel):' | |||||
539 | pull_request, auth_user=auth_user, translator=translator) |
|
539 | pull_request, auth_user=auth_user, translator=translator) | |
540 |
|
540 | |||
541 | self.notify_reviewers(pull_request, reviewer_ids) |
|
541 | self.notify_reviewers(pull_request, reviewer_ids) | |
542 |
self. |
|
542 | self.trigger_pull_request_hook( | |
543 | pull_request, created_by_user, 'create') |
|
543 | pull_request, created_by_user, 'create') | |
544 |
|
544 | |||
545 | creation_data = pull_request.get_api_data(with_merge_state=False) |
|
545 | creation_data = pull_request.get_api_data(with_merge_state=False) | |
@@ -549,7 +549,7 b' class PullRequestModel(BaseModel):' | |||||
549 |
|
549 | |||
550 | return pull_request |
|
550 | return pull_request | |
551 |
|
551 | |||
552 |
def |
|
552 | def trigger_pull_request_hook(self, pull_request, user, action, data=None): | |
553 | pull_request = self.__get_pull_request(pull_request) |
|
553 | pull_request = self.__get_pull_request(pull_request) | |
554 | target_scm = pull_request.target_repo.scm_instance() |
|
554 | target_scm = pull_request.target_repo.scm_instance() | |
555 | if action == 'create': |
|
555 | if action == 'create': | |
@@ -562,6 +562,12 b' class PullRequestModel(BaseModel):' | |||||
562 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook |
|
562 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook | |
563 | elif action == 'update': |
|
563 | elif action == 'update': | |
564 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook |
|
564 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook | |
|
565 | elif action == 'comment': | |||
|
566 | # dummy hook ! for comment. We want this function to handle all cases | |||
|
567 | def trigger_hook(*args, **kwargs): | |||
|
568 | pass | |||
|
569 | comment = data['comment'] | |||
|
570 | events.trigger(events.PullRequestCommentEvent(pull_request, comment)) | |||
565 | else: |
|
571 | else: | |
566 | return |
|
572 | return | |
567 |
|
573 | |||
@@ -569,7 +575,8 b' class PullRequestModel(BaseModel):' | |||||
569 | username=user.username, |
|
575 | username=user.username, | |
570 | repo_name=pull_request.target_repo.repo_name, |
|
576 | repo_name=pull_request.target_repo.repo_name, | |
571 | repo_alias=target_scm.alias, |
|
577 | repo_alias=target_scm.alias, | |
572 |
pull_request=pull_request |
|
578 | pull_request=pull_request, | |
|
579 | data=data) | |||
573 |
|
580 | |||
574 | def _get_commit_ids(self, pull_request): |
|
581 | def _get_commit_ids(self, pull_request): | |
575 | """ |
|
582 | """ | |
@@ -669,7 +676,7 b' class PullRequestModel(BaseModel):' | |||||
669 | # TODO: paris: replace invalidation with less radical solution |
|
676 | # TODO: paris: replace invalidation with less radical solution | |
670 | ScmModel().mark_for_invalidation( |
|
677 | ScmModel().mark_for_invalidation( | |
671 | pull_request.target_repo.repo_name) |
|
678 | pull_request.target_repo.repo_name) | |
672 |
self. |
|
679 | self.trigger_pull_request_hook(pull_request, user, 'merge') | |
673 |
|
680 | |||
674 | def has_valid_update_type(self, pull_request): |
|
681 | def has_valid_update_type(self, pull_request): | |
675 | source_ref_type = pull_request.source_ref_parts.type |
|
682 | source_ref_type = pull_request.source_ref_parts.type | |
@@ -839,8 +846,7 b' class PullRequestModel(BaseModel):' | |||||
839 | pull_request.source_ref_parts.commit_id, |
|
846 | pull_request.source_ref_parts.commit_id, | |
840 | pull_request_version.pull_request_version_id) |
|
847 | pull_request_version.pull_request_version_id) | |
841 | Session().commit() |
|
848 | Session().commit() | |
842 |
self. |
|
849 | self.trigger_pull_request_hook(pull_request, pull_request.author, 'update') | |
843 | pull_request, pull_request.author, 'update') |
|
|||
844 |
|
850 | |||
845 | return UpdateResponse( |
|
851 | return UpdateResponse( | |
846 | executed=True, reason=UpdateFailureReason.NONE, |
|
852 | executed=True, reason=UpdateFailureReason.NONE, | |
@@ -1174,7 +1180,7 b' class PullRequestModel(BaseModel):' | |||||
1174 | pull_request.status = PullRequest.STATUS_CLOSED |
|
1180 | pull_request.status = PullRequest.STATUS_CLOSED | |
1175 | pull_request.updated_on = datetime.datetime.now() |
|
1181 | pull_request.updated_on = datetime.datetime.now() | |
1176 | Session().add(pull_request) |
|
1182 | Session().add(pull_request) | |
1177 |
self. |
|
1183 | self.trigger_pull_request_hook( | |
1178 | pull_request, pull_request.author, 'close') |
|
1184 | pull_request, pull_request.author, 'close') | |
1179 |
|
1185 | |||
1180 | pr_data = pull_request.get_api_data(with_merge_state=False) |
|
1186 | pr_data = pull_request.get_api_data(with_merge_state=False) | |
@@ -1228,8 +1234,9 b' class PullRequestModel(BaseModel):' | |||||
1228 | # change the status, while if he's a reviewer this might change it. |
|
1234 | # change the status, while if he's a reviewer this might change it. | |
1229 | calculated_status = pull_request.calculated_review_status() |
|
1235 | calculated_status = pull_request.calculated_review_status() | |
1230 | if old_calculated_status != calculated_status: |
|
1236 | if old_calculated_status != calculated_status: | |
1231 |
self. |
|
1237 | self.trigger_pull_request_hook( | |
1232 |
pull_request, user, 'review_status_change' |
|
1238 | pull_request, user, 'review_status_change', | |
|
1239 | data={'status': calculated_status}) | |||
1233 |
|
1240 | |||
1234 | # finally close the PR |
|
1241 | # finally close the PR | |
1235 | PullRequestModel().close_pull_request( |
|
1242 | PullRequestModel().close_pull_request( |
@@ -69,7 +69,7 b' class TestPullRequestModel(object):' | |||||
69 | self.helper_patcher.start() |
|
69 | self.helper_patcher.start() | |
70 |
|
70 | |||
71 | self.hook_patcher = mock.patch.object(PullRequestModel, |
|
71 | self.hook_patcher = mock.patch.object(PullRequestModel, | |
72 |
' |
|
72 | 'trigger_pull_request_hook') | |
73 | self.hook_mock = self.hook_patcher.start() |
|
73 | self.hook_mock = self.hook_patcher.start() | |
74 |
|
74 | |||
75 | self.invalidation_patcher = mock.patch( |
|
75 | self.invalidation_patcher = mock.patch( |
General Comments 0
You need to be logged in to leave comments.
Login now