Changeset - 7d47e91dc1aa
[Not reviewed]
beta
0 2 0
Mads Kiilerich - 13 years ago 2013-03-26 01:23:35
madski@unity3d.com
pullrequests: use default_other_repo_info for the default other_ref selector
2 files changed with 5 insertions and 7 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/pullrequests.py
Show inline comments
 
@@ -59,226 +59,224 @@ log = logging.getLogger(__name__)
 

	
 
class PullrequestsController(BaseRepoController):
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def __before__(self):
 
        super(PullrequestsController, self).__before__()
 
        repo_model = RepoModel()
 
        c.users_array = repo_model.get_users_js()
 
        c.users_groups_array = repo_model.get_users_groups_js()
 

	
 
    def _get_repo_refs(self, repo, rev=None, branch_rev=None):
 
        """return a structure with repo's interesting changesets, suitable for
 
        the selectors in pullrequest.html"""
 
        branches = [('branch:%s:%s' % (k, v), k)
 
                    for k, v in repo.branches.iteritems()]
 
        bookmarks = [('book:%s:%s' % (k, v), k)
 
                     for k, v in repo.bookmarks.iteritems()]
 
        tags = [('tag:%s:%s' % (k, v), k)
 
                for k, v in repo.tags.iteritems()
 
                if k != 'tip']
 

	
 
        tip = repo.tags['tip']
 
        colontip = ':' + tip
 
        tips = [x[1] for x in branches + bookmarks + tags
 
                if x[0].endswith(colontip)]
 
        selected = 'tag:tip:%s' % tip
 
        special = [(selected, 'tip: %s' % ', '.join(tips))]
 

	
 
        if rev:
 
            selected = 'rev:%s:%s' % (rev, rev)
 
            special.append((selected, '%s: %s' % (_("Selected"), rev[:12])))
 

	
 
        # list named branches that has been merged to this named branch - it should probably merge back
 
        if branch_rev:
 
            # not restricting to merge() would also get branch point and be better
 
            # (especially because it would get the branch point) ... but is currently too expensive
 
            revs = ["sort(parents(branch(id('%s')) and merge()) - branch(id('%s')))" %
 
                    (branch_rev, branch_rev)]
 
            otherbranches = {}
 
            for i in scmutil.revrange(repo._repo, revs):
 
                cs = repo.get_changeset(i)
 
                otherbranches[cs.branch] = cs.raw_id
 
            for branch, node in otherbranches.iteritems():
 
                selected = 'branch:%s:%s' % (branch, node)
 
                special.append((selected, '%s: %s' % (_('Peer'), branch)))
 

	
 
        return [(special, _("Special")),
 
                (bookmarks, _("Bookmarks")),
 
                (branches, _("Branches")),
 
                (tags, _("Tags")),
 
                ], selected
 

	
 
    def _get_is_allowed_change_status(self, pull_request):
 
        owner = self.rhodecode_user.user_id == pull_request.user_id
 
        reviewer = self.rhodecode_user.user_id in [x.user_id for x in
 
                                                   pull_request.reviewers]
 
        return (self.rhodecode_user.admin or owner or reviewer)
 

	
 
    def show_all(self, repo_name):
 
        c.pull_requests = PullRequestModel().get_all(repo_name)
 
        c.repo_name = repo_name
 
        return render('/pullrequests/pullrequest_show_all.html')
 

	
 
    @NotAnonymous()
 
    def index(self):
 
        org_repo = c.rhodecode_db_repo
 

	
 
        if org_repo.scm_instance.alias != 'hg':
 
            log.error('Review not available for GIT REPOS')
 
            raise HTTPNotFound
 

	
 
        try:
 
            org_repo.scm_instance.get_changeset()
 
        except EmptyRepositoryError, e:
 
            h.flash(h.literal(_('There are no changesets yet')),
 
                    category='warning')
 
            redirect(url('summary_home', repo_name=org_repo.repo_name))
 

	
 
        org_rev = request.GET.get('rev_end')
 
        # rev_start is not directly useful - its parent could however be used
 
        # as default for other and thus give a simple compare view
 
        #other_rev = request.POST.get('rev_start')
 

	
 
        other_repos_info = {}
 

	
 
        c.org_repos = []
 
        c.org_repos.append((org_repo.repo_name, org_repo.repo_name))
 
        c.default_org_repo = org_repo.repo_name
 
        c.org_refs, c.default_org_ref = self._get_repo_refs(org_repo.scm_instance, org_rev)
 

	
 
        c.other_repos = []
 
        # add org repo to other so we can open pull request against itself
 
        c.other_repos.extend(c.org_repos)
 
        c.default_other_repo = org_repo.repo_name
 
        c.default_other_refs, c.default_other_ref = self._get_repo_refs(org_repo.scm_instance, branch_rev=org_rev)
 
        other_refs, other_ref = self._get_repo_refs(org_repo.scm_instance, branch_rev=org_rev)
 
        usr_data = lambda usr: dict(user_id=usr.user_id,
 
                                    username=usr.username,
 
                                    firstname=usr.firstname,
 
                                    lastname=usr.lastname,
 
                                    gravatar_link=h.gravatar_url(usr.email, 14))
 
        other_repos_info[org_repo.repo_name] = {
 
            'user': usr_data(org_repo.user),
 
            'description': org_repo.description,
 
            'revs': h.select('other_ref', c.default_other_ref,
 
                             c.default_other_refs, class_='refs')
 
            'revs': h.select('other_ref', other_ref, other_refs, class_='refs')
 
        }
 

	
 
        # gather forks and add to this list ... even though it is rare to
 
        # request forks to pull from their parent
 
        for fork in org_repo.forks:
 
            c.other_repos.append((fork.repo_name, fork.repo_name))
 
            refs, default_ref = self._get_repo_refs(fork.scm_instance)
 
            other_repos_info[fork.repo_name] = {
 
                'user': usr_data(fork.user),
 
                'description': fork.description,
 
                'revs': h.select('other_ref', default_ref, refs, class_='refs')
 
            }
 

	
 
        # add parents of this fork also, but only if it's not empty
 
        if org_repo.parent and org_repo.parent.scm_instance.revisions:
 
            c.default_other_repo = org_repo.parent.repo_name
 
            c.default_other_refs, c.default_other_ref = self._get_repo_refs(org_repo.parent.scm_instance)
 
            other_refs, other_ref = self._get_repo_refs(org_repo.parent.scm_instance)
 
            c.other_repos.append((org_repo.parent.repo_name, org_repo.parent.repo_name))
 
            other_repos_info[org_repo.parent.repo_name] = {
 
                'user': usr_data(org_repo.parent.user),
 
                'description': org_repo.parent.description,
 
                'revs': h.select('other_ref', c.default_other_ref,
 
                                 c.default_other_refs, class_='refs')
 
                'revs': h.select('other_ref', other_ref, other_refs, class_='refs')
 
            }
 

	
 
        c.default_other_repo_info = other_repos_info[c.default_other_repo]
 
        c.other_repos_info = json.dumps(other_repos_info)
 
        return render('/pullrequests/pullrequest.html')
 

	
 
    @NotAnonymous()
 
    def create(self, repo_name):
 
        repo = RepoModel()._get_repo(repo_name)
 
        try:
 
            _form = PullRequestForm(repo.repo_id)().to_python(request.POST)
 
        except formencode.Invalid, errors:
 
            log.error(traceback.format_exc())
 
            if errors.error_dict.get('revisions'):
 
                msg = 'Revisions: %s' % errors.error_dict['revisions']
 
            elif errors.error_dict.get('pullrequest_title'):
 
                msg = _('Pull request requires a title with min. 3 chars')
 
            else:
 
                msg = _('error during creation of pull request')
 

	
 
            h.flash(msg, 'error')
 
            return redirect(url('pullrequest_home', repo_name=repo_name))
 

	
 
        org_repo = _form['org_repo']
 
        org_ref = 'rev:merge:%s' % _form['merge_rev']
 
        other_repo = _form['other_repo']
 
        other_ref = 'rev:ancestor:%s' % _form['ancestor_rev']
 
        revisions = _form['revisions']
 
        reviewers = _form['review_members']
 

	
 
        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:
 
            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)
 
        if pull_request.is_closed():
 
            raise HTTPForbidden()
 
        #only owner or admin can update it
 
        owner = pull_request.author.user_id == c.rhodecode_user.user_id
 
        if h.HasPermissionAny('hg.admin', 'repository.admin')() or owner:
 
            reviewers_ids = map(int, filter(lambda v: v not in [None, ''],
 
                       request.POST.get('reviewers_ids', '').split(',')))
 

	
 
            PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
 
            Session().commit()
 
            return True
 
        raise HTTPForbidden()
 

	
 
    @NotAnonymous()
 
    @jsonify
 
    def delete(self, repo_name, pull_request_id):
 
        pull_request = PullRequest.get_or_404(pull_request_id)
 
        #only owner can delete it !
 
        if pull_request.author.user_id == c.rhodecode_user.user_id:
 
            PullRequestModel().delete(pull_request)
 
            Session().commit()
 
            h.flash(_('Successfully deleted pull request'),
 
                    category='success')
 
            return redirect(url('admin_settings_my_account', anchor='pullrequests'))
 
        raise HTTPForbidden()
 

	
 
    def _load_compare_data(self, pull_request, enable_comments=True):
 
        """
 
        Load context data needed for generating compare diff
 

	
 
        :param pull_request:
 
        :type pull_request:
 
        """
 
        org_repo = pull_request.org_repo
 
        (org_ref_type,
 
         org_ref_name,
 
         org_ref_rev) = pull_request.org_ref.split(':')
 

	
 
        other_repo = org_repo
 
        (other_ref_type,
 
         other_ref_name,
 
         other_ref_rev) = pull_request.other_ref.split(':')
rhodecode/templates/pullrequests/pullrequest.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${c.repo_name} ${_('New pull request')}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.repo_link(c.rhodecode_db_repo.groups_and_repo)}
 
    &raquo;
 
    ${_('new pull request')}
 
</%def>
 

	
 
<%def name="main()">
 
${self.context_bar('showpullrequest')}
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    ${h.form(url('pullrequest', repo_name=c.repo_name), method='post', id='pull_request_form')}
 
    <div style="float:left;padding:0px 30px 30px 30px">
 
        ##ORG
 
        <div style="float:left">
 
            <div>
 
                <span style="font-size: 20px">
 
                ${h.select('org_repo','',c.org_repos,class_='refs')}:${h.select('org_ref',c.default_org_ref,c.org_refs,class_='refs')}
 
                </span>
 
                 <div style="padding:5px 3px 3px 20px;">${c.rhodecode_db_repo.description}</div>
 
            </div>
 
            <div style="clear:both;padding-top: 10px"></div>
 
        </div>
 
          <div style="float:left;font-size:24px;padding:0px 20px">
 
          <img height=32 width=32 src="${h.url('/images/arrow_right_64.png')}"/>
 
          </div>
 

	
 
        ##OTHER, most Probably the PARENT OF THIS FORK
 
        <div style="float:left">
 
            <div>
 
                <span style="font-size: 20px">
 
                ${h.select('other_repo',c.default_other_repo,c.other_repos,class_='refs')}:${h.select('other_ref',c.default_other_ref,c.default_other_refs,class_='refs')}
 
                ${h.select('other_repo',c.default_other_repo,c.other_repos,class_='refs')}:${c.default_other_repo_info['revs']}
 
                </span>
 
                 <div id="other_repo_desc" style="padding:5px 3px 3px 20px;"></div>
 
            </div>
 
            <div style="clear:both;padding-top: 10px"></div>
 
        </div>
 
       <div style="clear:both;padding-top: 10px"></div>
 
       ## overview pulled by ajax
 
       <div style="float:left" id="pull_request_overview"></div>
 
       <div style="float:left;clear:both;padding:10px 10px 10px 0px;display:none">
 
            <a id="pull_request_overview_url" href="#">${_('Detailed compare view')}</a>
 
       </div>
 
     </div>
 
    <div style="float:left; border-left:1px dashed #eee">
 
        <h4>${_('Pull request reviewers')}</h4>
 
        <div id="reviewers" style="padding:0px 0px 0px 15px">
 
          ## members goes here !
 
          <div class="group_members_wrap">
 
            <ul id="review_members" class="group_members">
 
            %for member in [c.default_other_repo_info['user']]:
 
              <li id="reviewer_${member['user_id']}">
 
                <div class="reviewers_member">
 
                  <div class="gravatar"><img alt="gravatar" src="${member['gravatar_link']}"/> </div>
 
                  <div style="float:left">${member['firstname']} ${member['lastname']} (${_('owner')})</div>
 
                  <input type="hidden" value="${member['user_id']}" name="review_members" />
 
                  <span class="delete_icon action_button" onclick="removeReviewMember(${member['user_id']})"></span>
 
                </div>
 
              </li>
 
            %endfor
 
            </ul>
 
          </div>
 

	
 
          <div class='ac'>
 
            <div class="reviewer_ac">
 
               ${h.text('user', class_='yui-ac-input')}
 
               <span class="help-block">${_('Add reviewer to this pull request.')}</span>
 
               <div id="reviewers_container"></div>
 
            </div>
 
          </div>
 
        </div>
 
    </div>
 
    <h3>${_('Create new pull request')}</h3>
 

	
 
    <div class="form">
 
        <!-- fields -->
 

	
 
        <div class="fields">
 

	
 
             <div class="field">
 
                <div class="label">
 
                    <label for="pullrequest_title">${_('Title')}:</label>
 
                </div>
 
                <div class="input">
 
                    ${h.text('pullrequest_title',size=30)}
 
                </div>
 
             </div>
 

	
 
            <div class="field">
 
                <div class="label label-textarea">
 
                    <label for="pullrequest_desc">${_('Description')}:</label>
 
                </div>
 
                <div class="textarea text-area editor">
 
                    ${h.textarea('pullrequest_desc',size=30)}
 
                </div>
 
            </div>
 

	
 
            <div class="buttons">
 
                ${h.submit('save',_('Send pull request'),class_="ui-btn large")}
 
                ${h.reset('reset',_('Reset'),class_="ui-btn large")}
 
           </div>
 
        </div>
 
    </div>
 
    ${h.end_form()}
 

	
 
</div>
 

	
 
<script type="text/javascript">
 
  var _USERS_AC_DATA = ${c.users_array|n};
 
  var _GROUPS_AC_DATA = ${c.users_groups_array|n};
 
  PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA);
 

	
 
  var other_repos_info = ${c.other_repos_info|n};
 

	
 
  var otherrepoChanged = function(){
 
      var sel_box = YUQ('#pull_request_form #other_repo')[0];
 
      var repo_name = sel_box.options[sel_box.selectedIndex].value;
 

	
 
      YUD.get('other_repo_desc').innerHTML = other_repos_info[repo_name]['description'];
 
      // replace options of other_ref with the ones for the current other_repo
 
      var other_ref_selector = YUD.get('other_ref');
 
      var new_select = YUD.createElementFromMarkup(other_repos_info[repo_name]['revs']);
 
      var new_selectedIndex = new_select.selectedIndex;
 
      other_ref_selector.innerHTML = ""; // clear old options
 
      while (new_select.length > 0){ // children will be popped when appened to other_ref_selector
 
          other_ref_selector.appendChild(new_select.children[0]);
 
      }
 
      // browsers lost track of selected when appendChild was used
0 comments (0 inline, 0 general)