changeset 2677:4fbbc65e8cd5 beta

Forbid changing changset status when it is associated with a closed pull request - fixed some issues with cascade deleting repos with changeset statuses attached
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 30 Jul 2012 23:29:03 +0200
parents 1f4d4b8d72f5
children 04d2bcfbe7a6
files rhodecode/controllers/changeset.py rhodecode/lib/exceptions.py rhodecode/model/changeset_status.py rhodecode/model/db.py rhodecode/templates/changeset/changeset_file_comment.html
diffstat 5 files changed, 43 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/changeset.py	Mon Jul 30 22:45:43 2012 +0200
+++ b/rhodecode/controllers/changeset.py	Mon Jul 30 23:29:03 2012 +0200
@@ -49,6 +49,7 @@
 from rhodecode.model.meta import Session
 from rhodecode.lib.diffs import wrapped_diff
 from rhodecode.model.repo import RepoModel
+from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
 
 log = logging.getLogger(__name__)
 
@@ -388,18 +389,31 @@
 
         # get status if set !
         if status and change_status:
-            ChangesetStatusModel().set_status(
-                c.rhodecode_db_repo.repo_id,
-                status,
-                c.rhodecode_user.user_id,
-                comm,
-                revision=revision,
-            )
+            # if latest status was from pull request and it's closed
+            # disallow changing status ! 
+            # dont_allow_on_closed_pull_request = True !
+
+            try:
+                ChangesetStatusModel().set_status(
+                    c.rhodecode_db_repo.repo_id,
+                    status,
+                    c.rhodecode_user.user_id,
+                    comm,
+                    revision=revision,
+                    dont_allow_on_closed_pull_request=True
+                )
+            except StatusChangeOnClosedPullRequestError:
+                log.error(traceback.format_exc())
+                msg = _('Changing status on a changeset associated with'
+                        'a closed pull request is not allowed')
+                h.flash(msg, category='warning')
+                return redirect(h.url('changeset_home', repo_name=repo_name,
+                                      revision=revision))
         action_logger(self.rhodecode_user,
                       'user_commented_revision:%s' % revision,
                       c.rhodecode_db_repo, self.ip_addr, self.sa)
 
-        Session.commit()
+        Session().commit()
 
         if not request.environ.get('HTTP_X_PARTIAL_XHR'):
             return redirect(h.url('changeset_home', repo_name=repo_name,
@@ -422,7 +436,7 @@
         owner = lambda: co.author.user_id == c.rhodecode_user.user_id
         if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
             ChangesetCommentsModel().delete(comment=co)
-            Session.commit()
+            Session().commit()
             return True
         else:
             raise HTTPForbidden()
--- a/rhodecode/lib/exceptions.py	Mon Jul 30 22:45:43 2012 +0200
+++ b/rhodecode/lib/exceptions.py	Mon Jul 30 23:29:03 2012 +0200
@@ -50,3 +50,7 @@
 
 class UsersGroupsAssignedException(Exception):
     pass
+
+
+class StatusChangeOnClosedPullRequestError(Exception):
+    pass
\ No newline at end of file
--- a/rhodecode/model/changeset_status.py	Mon Jul 30 22:45:43 2012 +0200
+++ b/rhodecode/model/changeset_status.py	Mon Jul 30 23:29:03 2012 +0200
@@ -28,6 +28,7 @@
 
 from rhodecode.model import BaseModel
 from rhodecode.model.db import ChangesetStatus, PullRequest
+from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError
 
 log = logging.getLogger(__name__)
 
@@ -111,7 +112,7 @@
         return str(st)
 
     def set_status(self, repo, status, user, comment, revision=None,
-                   pull_request=None):
+                   pull_request=None, dont_allow_on_closed_pull_request=False):
         """
         Creates new status for changeset or updates the old ones bumping their
         version, leaving the current status at
@@ -126,6 +127,9 @@
         :type user:
         :param comment:
         :type comment:
+        :param dont_allow_on_closed_pull_request: don't allow a status change
+            if last status was for pull request and it's closed. We shouldn't
+            mess around this manually
         """
         repo = self._get_repo(repo)
 
@@ -140,6 +144,14 @@
             q = q.filter(ChangesetStatus.pull_request == pull_request)
         cur_statuses = q.all()
 
+        #if statuses exists and last is associated with a closed pull request
+        # we need to check if we can allow this status change
+        if (dont_allow_on_closed_pull_request and cur_statuses 
+            and cur_statuses[0].pull_request.status == PullRequest.STATUS_CLOSED):
+            raise StatusChangeOnClosedPullRequestError(
+                'Changing status on closed pull request is not allowed'
+            )
+
         if cur_statuses:
             for st in cur_statuses:
                 st.version += 1
--- a/rhodecode/model/db.py	Mon Jul 30 22:45:43 2012 +0200
+++ b/rhodecode/model/db.py	Mon Jul 30 23:29:03 2012 +0200
@@ -1449,7 +1449,7 @@
 
     author = relationship('User', lazy='joined')
     repo = relationship('Repository')
-    status_change = relationship('ChangesetStatus', uselist=False)
+    status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan")
     pull_request = relationship('PullRequest', lazy='joined')
 
     @classmethod
--- a/rhodecode/templates/changeset/changeset_file_comment.html	Mon Jul 30 22:45:43 2012 +0200
+++ b/rhodecode/templates/changeset/changeset_file_comment.html	Mon Jul 30 23:29:03 2012 +0200
@@ -17,8 +17,8 @@
         %if co.status_change:
            <div  style="float:left" class="changeset-status-container">
              <div style="float:left;padding:0px 2px 0px 2px"><span style="font-size: 18px;">&rsaquo;</span></div>
-             <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change.status_lbl}</div>
-             <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change.status))}" /></div>
+             <div title="${_('Changeset status')}" class="changeset-status-lbl"> ${co.status_change[0].status_lbl}</div>
+             <div class="changeset-status-ico"><img src="${h.url(str('/images/icons/flag_status_%s.png' % co.status_change[0].status))}" /></div>
            </div>
         %endif
       %if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id: