Show More
@@ -49,6 +49,7 b' from rhodecode.model.changeset_status im' | |||||
49 | from rhodecode.model.meta import Session |
|
49 | from rhodecode.model.meta import Session | |
50 | from rhodecode.lib.diffs import wrapped_diff |
|
50 | from rhodecode.lib.diffs import wrapped_diff | |
51 | from rhodecode.model.repo import RepoModel |
|
51 | from rhodecode.model.repo import RepoModel | |
|
52 | from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError | |||
52 |
|
53 | |||
53 | log = logging.getLogger(__name__) |
|
54 | log = logging.getLogger(__name__) | |
54 |
|
55 | |||
@@ -388,18 +389,31 b' class ChangesetController(BaseRepoContro' | |||||
388 |
|
389 | |||
389 | # get status if set ! |
|
390 | # get status if set ! | |
390 | if status and change_status: |
|
391 | if status and change_status: | |
391 | ChangesetStatusModel().set_status( |
|
392 | # if latest status was from pull request and it's closed | |
392 | c.rhodecode_db_repo.repo_id, |
|
393 | # disallow changing status ! | |
393 | status, |
|
394 | # dont_allow_on_closed_pull_request = True ! | |
394 | c.rhodecode_user.user_id, |
|
395 | ||
395 |
|
|
396 | try: | |
396 | revision=revision, |
|
397 | ChangesetStatusModel().set_status( | |
397 | ) |
|
398 | c.rhodecode_db_repo.repo_id, | |
|
399 | status, | |||
|
400 | c.rhodecode_user.user_id, | |||
|
401 | comm, | |||
|
402 | revision=revision, | |||
|
403 | dont_allow_on_closed_pull_request=True | |||
|
404 | ) | |||
|
405 | except StatusChangeOnClosedPullRequestError: | |||
|
406 | log.error(traceback.format_exc()) | |||
|
407 | msg = _('Changing status on a changeset associated with' | |||
|
408 | 'a closed pull request is not allowed') | |||
|
409 | h.flash(msg, category='warning') | |||
|
410 | return redirect(h.url('changeset_home', repo_name=repo_name, | |||
|
411 | revision=revision)) | |||
398 | action_logger(self.rhodecode_user, |
|
412 | action_logger(self.rhodecode_user, | |
399 | 'user_commented_revision:%s' % revision, |
|
413 | 'user_commented_revision:%s' % revision, | |
400 | c.rhodecode_db_repo, self.ip_addr, self.sa) |
|
414 | c.rhodecode_db_repo, self.ip_addr, self.sa) | |
401 |
|
415 | |||
402 | Session.commit() |
|
416 | Session().commit() | |
403 |
|
417 | |||
404 | if not request.environ.get('HTTP_X_PARTIAL_XHR'): |
|
418 | if not request.environ.get('HTTP_X_PARTIAL_XHR'): | |
405 | return redirect(h.url('changeset_home', repo_name=repo_name, |
|
419 | return redirect(h.url('changeset_home', repo_name=repo_name, | |
@@ -422,7 +436,7 b' class ChangesetController(BaseRepoContro' | |||||
422 | owner = lambda: co.author.user_id == c.rhodecode_user.user_id |
|
436 | owner = lambda: co.author.user_id == c.rhodecode_user.user_id | |
423 | if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner: |
|
437 | if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner: | |
424 | ChangesetCommentsModel().delete(comment=co) |
|
438 | ChangesetCommentsModel().delete(comment=co) | |
425 | Session.commit() |
|
439 | Session().commit() | |
426 | return True |
|
440 | return True | |
427 | else: |
|
441 | else: | |
428 | raise HTTPForbidden() |
|
442 | raise HTTPForbidden() |
@@ -50,3 +50,7 b' class UserOwnsReposException(Exception):' | |||||
50 |
|
50 | |||
51 | class UsersGroupsAssignedException(Exception): |
|
51 | class UsersGroupsAssignedException(Exception): | |
52 | pass |
|
52 | pass | |
|
53 | ||||
|
54 | ||||
|
55 | class StatusChangeOnClosedPullRequestError(Exception): | |||
|
56 | pass No newline at end of file |
@@ -28,6 +28,7 b' from collections import defaultdict' | |||||
28 |
|
28 | |||
29 | from rhodecode.model import BaseModel |
|
29 | from rhodecode.model import BaseModel | |
30 | from rhodecode.model.db import ChangesetStatus, PullRequest |
|
30 | from rhodecode.model.db import ChangesetStatus, PullRequest | |
|
31 | from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError | |||
31 |
|
32 | |||
32 | log = logging.getLogger(__name__) |
|
33 | log = logging.getLogger(__name__) | |
33 |
|
34 | |||
@@ -111,7 +112,7 b' class ChangesetStatusModel(BaseModel):' | |||||
111 | return str(st) |
|
112 | return str(st) | |
112 |
|
113 | |||
113 | def set_status(self, repo, status, user, comment, revision=None, |
|
114 | def set_status(self, repo, status, user, comment, revision=None, | |
114 | pull_request=None): |
|
115 | pull_request=None, dont_allow_on_closed_pull_request=False): | |
115 | """ |
|
116 | """ | |
116 | Creates new status for changeset or updates the old ones bumping their |
|
117 | Creates new status for changeset or updates the old ones bumping their | |
117 | version, leaving the current status at |
|
118 | version, leaving the current status at | |
@@ -126,6 +127,9 b' class ChangesetStatusModel(BaseModel):' | |||||
126 | :type user: |
|
127 | :type user: | |
127 | :param comment: |
|
128 | :param comment: | |
128 | :type comment: |
|
129 | :type comment: | |
|
130 | :param dont_allow_on_closed_pull_request: don't allow a status change | |||
|
131 | if last status was for pull request and it's closed. We shouldn't | |||
|
132 | mess around this manually | |||
129 | """ |
|
133 | """ | |
130 | repo = self._get_repo(repo) |
|
134 | repo = self._get_repo(repo) | |
131 |
|
135 | |||
@@ -140,6 +144,14 b' class ChangesetStatusModel(BaseModel):' | |||||
140 | q = q.filter(ChangesetStatus.pull_request == pull_request) |
|
144 | q = q.filter(ChangesetStatus.pull_request == pull_request) | |
141 | cur_statuses = q.all() |
|
145 | cur_statuses = q.all() | |
142 |
|
146 | |||
|
147 | #if statuses exists and last is associated with a closed pull request | |||
|
148 | # we need to check if we can allow this status change | |||
|
149 | if (dont_allow_on_closed_pull_request and cur_statuses | |||
|
150 | and cur_statuses[0].pull_request.status == PullRequest.STATUS_CLOSED): | |||
|
151 | raise StatusChangeOnClosedPullRequestError( | |||
|
152 | 'Changing status on closed pull request is not allowed' | |||
|
153 | ) | |||
|
154 | ||||
143 | if cur_statuses: |
|
155 | if cur_statuses: | |
144 | for st in cur_statuses: |
|
156 | for st in cur_statuses: | |
145 | st.version += 1 |
|
157 | st.version += 1 |
@@ -1449,7 +1449,7 b' class ChangesetComment(Base, BaseModel):' | |||||
1449 |
|
1449 | |||
1450 | author = relationship('User', lazy='joined') |
|
1450 | author = relationship('User', lazy='joined') | |
1451 | repo = relationship('Repository') |
|
1451 | repo = relationship('Repository') | |
1452 |
status_change = relationship('ChangesetStatus', |
|
1452 | status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") | |
1453 | pull_request = relationship('PullRequest', lazy='joined') |
|
1453 | pull_request = relationship('PullRequest', lazy='joined') | |
1454 |
|
1454 | |||
1455 | @classmethod |
|
1455 | @classmethod |
@@ -17,8 +17,8 b'' | |||||
17 | %if co.status_change: |
|
17 | %if co.status_change: | |
18 | <div style="float:left" class="changeset-status-container"> |
|
18 | <div style="float:left" class="changeset-status-container"> | |
19 | <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">›</span></div> |
|
19 | <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">›</span></div> | |
20 | <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change.status_lbl}</div> |
|
20 | <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change[0].status_lbl}</div> | |
21 | <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change.status))}" /></div> |
|
21 | <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change[0].status))}" /></div> | |
22 | </div> |
|
22 | </div> | |
23 | %endif |
|
23 | %endif | |
24 | %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id: |
|
24 | %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id: |
General Comments 0
You need to be logged in to leave comments.
Login now