Changeset - 5d1d25c1c700
[Not reviewed]
beta
0 5 0
Marcin Kuzminski - 13 years ago 2013-01-19 19:42:37
marcin@python-works.com
set the status of changesets initially on pull request, and make sure we care of version collisions.
Fixes issues #690 and #587
5 files changed with 28 insertions and 13 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/pullrequests.py
Show inline comments
 
@@ -215,24 +215,25 @@ class PullrequestsController(BaseRepoCon
 
        title = _form['pullrequest_title']
 
        description = _form['pullrequest_desc']
 

	
 
        try:
 
            pull_request = PullRequestModel().create(
 
                self.rhodecode_user.user_id, org_repo, org_ref, other_repo,
 
                other_ref, revisions, reviewers, title, description
 
            )
 
            Session().commit()
 
            h.flash(_('Successfully opened new pull request'),
 
                    category='success')
 
        except Exception:
 
            raise
 
            h.flash(_('Error occurred during sending pull request'),
 
                    category='error')
 
            log.error(traceback.format_exc())
 
            return redirect(url('pullrequest_home', repo_name=repo_name))
 

	
 
        return redirect(url('pullrequest_show', repo_name=other_repo,
 
                            pull_request_id=pull_request.pull_request_id))
 

	
 
    @NotAnonymous()
 
    @jsonify
 
    def update(self, repo_name, pull_request_id):
 
        pull_request = PullRequest.get_or_404(pull_request_id)
rhodecode/model/changeset_status.py
Show inline comments
 
@@ -102,66 +102,69 @@ class ChangesetStatusModel(BaseModel):
 
        :param pull_request: pull_request reference
 
        :type:
 
        """
 
        q = self._get_status_query(repo, revision, pull_request)
 

	
 
        # need to use first here since there can be multiple statuses
 
        # returned from pull_request
 
        status = q.first()
 
        status = status.status if status else status
 
        st = status or ChangesetStatus.DEFAULT
 
        return str(st)
 

	
 
    def set_status(self, repo, status, user, comment, revision=None,
 
    def set_status(self, repo, status, user, comment=None, revision=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
 

	
 
        :param repo:
 
        :type repo:
 
        :param revision:
 
        :type revision:
 
        :param status:
 
        :type status:
 
        :param user:
 
        :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)
 

	
 
        q = ChangesetStatus.query()
 

	
 
        if not comment:
 
            from rhodecode.model.comment import ChangesetCommentsModel
 
            comment = ChangesetCommentsModel().create(
 
                text='Auto status change',
 
                repo=repo,
 
                user=user,
 
                pull_request=pull_request,
 
            )
 
        if revision:
 
            q = q.filter(ChangesetStatus.repo == repo)
 
            q = q.filter(ChangesetStatus.revision == revision)
 
        elif pull_request:
 
            pull_request = self.__get_pull_request(pull_request)
 
            q = q.filter(ChangesetStatus.repo == pull_request.org_repo)
 
            q = q.filter(ChangesetStatus.pull_request == pull_request)
 
            q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
 
        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 getattr(cur_statuses[0].pull_request, 'status', '')
 
                == PullRequest.STATUS_CLOSED):
 
            raise StatusChangeOnClosedPullRequestError(
 
                'Changing status on closed pull request is not allowed'
 
            )
 

	
 
        #update all current statuses with older version
 
        if cur_statuses:
 
            for st in cur_statuses:
 
                st.version += 1
 
                self.sa.add(st)
 

	
 
        def _create_status(user, repo, status, comment, revision, pull_request):
 
            new_status = ChangesetStatus()
 
            new_status.author = self._get_user(user)
 
            new_status.repo = self._get_repo(repo)
 
            new_status.status = status
 
            new_status.comment = comment
 
            new_status.revision = revision
rhodecode/model/forms.py
Show inline comments
 
@@ -356,19 +356,20 @@ def UserExtraIpForm():
 

	
 

	
 
def PullRequestForm(repo_id):
 
    class _PullRequestForm(formencode.Schema):
 
        allow_extra_fields = True
 
        filter_extra_fields = True
 

	
 
        user = v.UnicodeString(strip=True, required=True)
 
        org_repo = v.UnicodeString(strip=True, required=True)
 
        org_ref = v.UnicodeString(strip=True, required=True)
 
        other_repo = v.UnicodeString(strip=True, required=True)
 
        other_ref = v.UnicodeString(strip=True, required=True)
 
        revisions = All(v.NotReviewedRevisions(repo_id)(), v.UniqueList(not_empty=True))
 
        revisions = All(#v.NotReviewedRevisions(repo_id)(),
 
                        v.UniqueList(not_empty=True))
 
        review_members = v.UniqueList(not_empty=True)
 

	
 
        pullrequest_title = v.UnicodeString(strip=True, required=True, min=3)
 
        pullrequest_desc = v.UnicodeString(strip=True, required=False)
 

	
 
    return _PullRequestForm
rhodecode/model/pull_request.py
Show inline comments
 
@@ -24,69 +24,79 @@
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 
import binascii
 
import datetime
 
import re
 

	
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.model.meta import Session
 
from rhodecode.lib import helpers as h
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification
 
from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification,\
 
    ChangesetStatus
 
from rhodecode.model.notification import NotificationModel
 
from rhodecode.lib.utils2 import safe_unicode
 

	
 
from rhodecode.lib.vcs.utils.hgcompat import discovery, localrepo, scmutil, \
 
    findcommonoutgoing
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class PullRequestModel(BaseModel):
 

	
 
    cls = PullRequest
 

	
 
    def __get_pull_request(self, pull_request):
 
        return self._get_instance(PullRequest, pull_request)
 

	
 
    def get_all(self, repo):
 
        repo = self._get_repo(repo)
 
        return PullRequest.query().filter(PullRequest.other_repo == repo).all()
 

	
 
    def create(self, created_by, org_repo, org_ref, other_repo,
 
               other_ref, revisions, reviewers, title, description=None):
 
    def create(self, created_by, org_repo, org_ref, other_repo, other_ref,
 
               revisions, reviewers, title, description=None):
 
        from rhodecode.model.changeset_status import ChangesetStatusModel
 

	
 
        created_by_user = self._get_user(created_by)
 
        org_repo = self._get_repo(org_repo)
 
        other_repo = self._get_repo(other_repo)
 

	
 
        new = PullRequest()
 
        new.org_repo = org_repo
 
        new.org_ref = org_ref
 
        new.other_repo = other_repo
 
        new.other_ref = other_ref
 
        new.revisions = revisions
 
        new.title = title
 
        new.description = description
 
        new.author = created_by_user
 
        self.sa.add(new)
 
        Session().flush()
 
        #members
 
        for member in reviewers:
 
            _usr = self._get_user(member)
 
            reviewer = PullRequestReviewers(_usr, new)
 
            self.sa.add(reviewer)
 

	
 
        #reset state to under-review
 
        ChangesetStatusModel().set_status(
 
            repo=org_repo,
 
            status=ChangesetStatus.STATUS_UNDER_REVIEW,
 
            user=created_by_user,
 
            pull_request=new
 
        )
 

	
 
        #notification to reviewers
 
        notif = NotificationModel()
 

	
 
        pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name,
 
                       pull_request_id=new.pull_request_id,
 
                       qualified=True,
 
        )
 
        subject = safe_unicode(
 
            h.link_to(
 
              _('%(user)s wants you to review pull request #%(pr_id)s') % \
 
                {'user': created_by_user.username,
 
                 'pr_id': new.pull_request_id},
rhodecode/templates/pullrequests/pullrequest_show.html
Show inline comments
 
@@ -56,25 +56,25 @@
 
              <label>${_('Origin repository')}:</label>
 
          </div>
 
          <div class="input">
 
              <div>
 
             ##%if h.is_hg(c.pull_request.org_repo):
 
             ##  <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
 
             ##%elif h.is_git(c.pull_request.org_repo):
 
             ##  <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
 
             ##%endif
 
              <span class="spantag">${c.pull_request.org_ref_parts[0]}</span>
 
              :
 
              <span class="spantag">${c.pull_request.org_ref_parts[1]}</span>             
 
              <span>${c.pull_request.org_repo.clone_url()}</span> 
 
              <span><a href="${h.url('summary_home', repo_name=c.pull_request.org_repo.repo_name)}">${c.pull_request.org_repo.clone_url()}</a></span> 
 
              </div>
 
          </div>
 
         </div>         
 
      </div>
 
    </div>
 
    <div style="white-space:pre-wrap;padding:3px 3px 5px 20px">${h.literal(c.pull_request.description)}</div>
 
    <div style="padding:4px 4px 10px 20px">
 
      <div>${_('Created on')}: ${h.fmt_date(c.pull_request.created_on)}</div>
 
    </div>
 

	
 
    <div style="overflow: auto;">
 
      ##DIFF
0 comments (0 inline, 0 general)