Changeset - d42d7b2a3b2f
[Not reviewed]
default
0 4 0
Mads Kiilerich - 11 years ago 2015-01-21 17:35:11
madski@unity3d.com
pullrequests: reintroduce 'update' functionality as separate submit button in the big form
4 files changed with 42 insertions and 34 deletions:
0 comments (0 inline, 0 general)
kallithea/controllers/pullrequests.py
Show inline comments
 
@@ -356,60 +356,46 @@ class PullrequestsController(BaseRepoCon
 
            )
 
            Session().commit()
 
            h.flash(_('Successfully opened new pull request'),
 
                    category='success')
 
        except Exception:
 
            h.flash(_('Error occurred while creating pull request'),
 
                    category='error')
 
            log.error(traceback.format_exc())
 
            return redirect(url('pullrequest_home', repo_name=repo_name))
 

	
 
        return redirect(pull_request.url())
 

	
 
    @LoginRequired()
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def copy_update(self, repo_name, pull_request_id):
 
        old_pull_request = PullRequest.get_or_404(pull_request_id)
 
        assert old_pull_request.other_repo.repo_name == repo_name
 
        if old_pull_request.is_closed():
 
            raise HTTPForbidden()
 

	
 
    def create_update(self, old_pull_request, updaterev, title, description, reviewers_ids):
 
        org_repo = RepoModel()._get_repo(old_pull_request.org_repo.repo_name)
 
        org_ref_type, org_ref_name, org_rev = old_pull_request.org_ref.split(':')
 
        updaterev = request.POST.get('updaterev')
 
        if updaterev:
 
            new_org_rev = self._get_ref_rev(org_repo, 'rev', updaterev)
 
        else:
 
            # assert org_ref_type == 'branch', org_ref_type # TODO: what if not?
 
            new_org_rev = self._get_ref_rev(org_repo, org_ref_type, org_ref_name)
 

	
 
        other_repo = RepoModel()._get_repo(old_pull_request.other_repo.repo_name)
 
        other_ref_type, other_ref_name, other_rev = old_pull_request.other_ref.split(':') # other_rev is ancestor
 
        #assert other_ref_type == 'branch', other_ref_type # TODO: what if not?
 
        new_other_rev = self._get_ref_rev(other_repo, other_ref_type, other_ref_name)
 

	
 
        cs_ranges, _cs_ranges_not, ancestor_rev = CompareController._get_changesets(org_repo.scm_instance.alias,
 
            other_repo.scm_instance, new_other_rev, # org and other "swapped"
 
            org_repo.scm_instance, new_org_rev)
 

	
 
        old_revisions = set(old_pull_request.revisions)
 
        revisions = [cs.raw_id for cs in cs_ranges]
 
        new_revisions = [r for r in revisions if r not in old_revisions]
 
        lost = old_revisions.difference(revisions)
 

	
 
        infos = ['This is an update of %s "%s".' %
 
                 (h.canonical_url('pullrequest_show', repo_name=old_pull_request.other_repo.repo_name,
 
                      pull_request_id=pull_request_id),
 
                      pull_request_id=old_pull_request.pull_request_id),
 
                  old_pull_request.title)]
 

	
 
        if lost:
 
            infos.append(_('Missing changesets since the previous version:'))
 
            for r in old_pull_request.revisions:
 
                if r in lost:
 
                    rev_desc = org_repo.get_changeset(r).message.split('\n')[0]
 
                    infos.append('  %s "%s"' % (h.short_id(r), rev_desc))
 

	
 
        if new_revisions:
 
            infos.append(_('New changesets on %s %s since the previous version:') % (org_ref_type, org_ref_name))
 
            for r in reversed(revisions):
 
@@ -426,92 +412,96 @@ class PullrequestsController(BaseRepoCon
 
                                 )) # note: linear diff, merge or not doesn't matter
 
            else:
 
                infos.append(_('This pull request is based on another %s revision and there is no simple diff.') % other_ref_name)
 
        else:
 
           infos.append(_('No changes found on %s %s since previous version.') % (org_ref_type, org_ref_name))
 
           # TODO: fail?
 

	
 
        # hack: ancestor_rev is not an other_ref but we want to show the
 
        # requested destination and have the exact ancestor
 
        new_other_ref = '%s:%s:%s' % (other_ref_type, other_ref_name, ancestor_rev)
 
        new_org_ref = '%s:%s:%s' % (org_ref_type, org_ref_name, new_org_rev)
 

	
 
        reviewers_ids = [r.user_id for r in old_pull_request.reviewers]
 

	
 
        try:
 
            old_title, old_v = re.match(r'(.*)\(v(\d+)\)\s*$', old_pull_request.title).groups()
 
            title, old_v = re.match(r'(.*)\(v(\d+)\)\s*$', title).groups()
 
            v = int(old_v) + 1
 
        except (AttributeError, ValueError):
 
            old_title = old_pull_request.title
 
            v = 2
 
        title = '%s (v%s)' % (old_title.strip(), v)
 
        title = '%s (v%s)' % (title.strip(), v)
 

	
 
        # using a mail-like separator, insert new update info at the top of the list
 
        descriptions = old_pull_request.description.replace('\r\n', '\n').split('\n-- \n', 1)
 
        descriptions = description.replace('\r\n', '\n').split('\n-- \n', 1)
 
        description = descriptions[0].strip() + '\n\n-- \n' + '\n'.join(infos)
 
        if len(descriptions) > 1:
 
            description += '\n\n' + descriptions[1].strip()
 

	
 
        try:
 
            pull_request = PullRequestModel().create(
 
                self.authuser.user_id,
 
                old_pull_request.org_repo.repo_name, new_org_ref,
 
                old_pull_request.other_repo.repo_name, new_other_ref,
 
                revisions, reviewers_ids, title, description
 
            )
 
        except Exception:
 
            h.flash(_('Error occurred while creating pull request'),
 
                    category='error')
 
            log.error(traceback.format_exc())
 
            return redirect(old_pull_request.url())
 

	
 
        ChangesetCommentsModel().create(
 
            text=_('Closed, replaced by %s .') % h.canonical_url('pullrequest_show',
 
                                                   repo_name=old_pull_request.other_repo.repo_name,
 
                                                   pull_request_id=pull_request.pull_request_id),
 
            repo=old_pull_request.other_repo.repo_id,
 
            user=c.authuser.user_id,
 
            pull_request=pull_request_id,
 
            pull_request=old_pull_request.pull_request_id,
 
            closing_pr=True)
 
        PullRequestModel().close_pull_request(pull_request_id)
 
        PullRequestModel().close_pull_request(old_pull_request.pull_request_id)
 

	
 
        Session().commit()
 
        h.flash(_('Pull request update created'),
 
                category='success')
 

	
 
        return redirect(pull_request.url())
 

	
 
    # pullrequest_post for PR editing
 
    @LoginRequired()
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def post(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.authuser.user_id
 
        repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
 
        if not (h.HasPermissionAny('hg.admin') or repo_admin or owner):
 
            raise HTTPForbidden()
 

	
 
        _form = PullRequestPostForm()().to_python(request.POST)
 
        reviewers_ids = [int(s) for s in _form['review_members']]
 

	
 
        if _form['updaterev']:
 
            return self.create_update(pull_request,
 
                                      _form['updaterev'],
 
                                      _form['pullrequest_title'],
 
                                      _form['pullrequest_desc'],
 
                                      reviewers_ids)
 

	
 
        old_description = pull_request.description
 
        pull_request.title = _form['pullrequest_title']
 
        pull_request.description = _form['pullrequest_desc'].strip() or _('No description')
 
        PullRequestModel().mention_from_description(pull_request, old_description)
 

	
 
        reviewers_ids = [int(s) for s in _form['review_members']]
 
        PullRequestModel().update_reviewers(pull_request_id, reviewers_ids)
 

	
 
        Session().commit()
 
        h.flash(_('Pull request updated'), category='success')
 

	
 
        return redirect(pull_request.url())
 

	
 
    @LoginRequired()
 
    @NotAnonymous()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    @jsonify
kallithea/model/forms.py
Show inline comments
 
@@ -496,24 +496,25 @@ def PullRequestForm(repo_id):
 

	
 
    return _PullRequestForm
 

	
 

	
 
def PullRequestPostForm():
 
    class _PullRequestPostForm(formencode.Schema):
 
        allow_extra_fields = True
 
        filter_extra_fields = True
 

	
 
        pullrequest_title = v.UnicodeString(strip=True, required=True)
 
        pullrequest_desc = v.UnicodeString(strip=True, required=False)
 
        review_members = v.Set()
 
        updaterev = v.UnicodeString(strip=True, required=False, if_missing=None)
 

	
 
    return _PullRequestPostForm
 

	
 

	
 
def GistForm(lifetime_options):
 
    class _GistForm(formencode.Schema):
 

	
 
        filename = All(v.BasePath()(),
 
                       v.UnicodeString(strip=True, required=False))
 
        description = v.UnicodeString(required=False, if_missing=u'')
 
        lifetime = v.OneOf(lifetime_options)
 
        mimetype = v.UnicodeString(required=False, if_missing=None)
kallithea/public/css/style.css
Show inline comments
 
@@ -3481,24 +3481,25 @@ input.btn {
 
    line-height: inherit;
 
}
 

	
 
.btn::-moz-focus-inner {
 
    border: 0;
 
    padding: 0;
 
}
 

	
 
.btn.badge {
 
    cursor: default !important;
 
}
 

	
 
input[disabled].btn,
 
.btn.disabled {
 
    color: #999;
 
}
 

	
 
.btn.btn-danger.disabled {
 
    color: #eee;
 
    background-color: #c77;
 
    border-color: #b66
 
}
 

	
 
.btn.btn-small {
 
    padding: 2px 6px;
kallithea/templates/pullrequests/pullrequest_show.html
Show inline comments
 
@@ -164,43 +164,51 @@ ${self.repo_context_bar('showpullrequest
 
                  <span><a href="mailto:${c.pull_request.author.email}">${c.pull_request.author.email}</a></span><br/>
 
              </div>
 
          </div>
 
        </div>
 

	
 
        <div class="field">
 
            <div class="label-summary">
 
              <label>${_('Update')}:</label>
 
            </div>
 
            <div class="input">
 
              <div class="msg-div">${c.update_msg}</div>
 
              %if c.available:
 
              <div style="max-height:200px; overflow-y:auto; overflow-x:hidden; margin-bottom: 10px">
 
              <div id="updaterevs" style="max-height:200px; overflow-y:auto; overflow-x:hidden; margin-bottom: 10px">
 
                <table class="noborder">
 
                  %for cnt, cs in enumerate(c.available):
 
                    <tr>
 
                    <td>${h.radio(name='updaterev', value=cs.raw_id)}</td>
 
                      %if cs.revision == c.cs_ranges[-1].revision:
 
                        <td>
 
                          %if editable:
 
                            ${h.radio(name='updaterev', value='')}
 
                          %endif
 
                        </td>
 
                        <td colspan="2">${_("Current revision - no change")}</td>
 
                      %else:
 
                        <td>
 
                          %if editable:
 
                            ${h.radio(name='updaterev', value=cs.raw_id)}
 
                          %endif
 
                        </td>
 
                    <td>${h.link_to(h.show_id(cs),h.url('changeset_home',repo_name=c.cs_repo.repo_name,revision=cs.raw_id))}</td>
 
                    <td><div class="message" style="white-space:normal; height:1.1em; max-width: 500px; padding:0">${h.urlify_commit(cs.message, c.repo_name)}</div></td>
 
                      %endif
 
                    </tr>
 
                  %endfor
 
                </table>
 
              </div>
 
              %endif
 
              <div class="msg-div">${c.update_msg_other}</div>
 
            </div>
 
            %if editable and c.available:
 
              <div class="buttons">
 
                ${h.submit('copy_update',_('Create Pull Request Update'),class_="btn btn-small")}
 
              </div>
 
            %endif
 
        </div>
 
      </div>
 
    </div>
 
    ## REVIEWERS
 
    <div style="float:left; border-left:1px dashed #eee">
 
        <div class="pr-details-title">${_('Pull Request Reviewers')}</div>
 
        <div id="reviewers" style="padding:0px 0px 5px 10px">
 
          ## members goes here !
 
          <div>
 
            <ul id="review_members" class="group_members">
 
            %for member,status in c.pull_request_reviewers:
 
              <li id="reviewer_${member.user_id}">
 
@@ -226,26 +234,27 @@ ${self.repo_context_bar('showpullrequest
 
            <div class="reviewer_ac">
 
               ${h.text('user', class_='yui-ac-input',placeholder=_('Type name of reviewer to add'))}
 
               <div id="reviewers_container"></div>
 
            </div>
 
          </div>
 
          %endif
 
        </div>
 
    </div>
 
    <div class="form" style="clear:both">
 
      <div class="fields">
 
        %if editable:
 
          <div class="buttons">
 
            ${h.submit('pr-form-save',_('Save'),class_="btn btn-small")}
 
            ${h.reset('pr-form-reset',_('Cancel'),class_="btn btn-small")}
 
            ${h.submit('pr-form-save',_('Save Changes'),class_="btn btn-small")}
 
            ${h.submit('pr-form-clone',_('Save as New Pull Request'),class_="btn btn-small",disabled='disabled')}
 
            ${h.reset('pr-form-reset',_('Cancel Changes'),class_="btn btn-small")}
 
          </div>
 
        %endif
 
      </div>
 
    </div>
 
  ${h.end_form()}
 
</div>
 

	
 
<div class="box">
 
    <div class="title">
 
      <div class="breadcrumbs">${_('Pull Request Content')}</div>
 
    </div>
 
    <div class="table">
 
@@ -335,28 +344,35 @@ ${self.repo_context_bar('showpullrequest
 

	
 
          $('.add-bubble').click(function(e){
 
              var tr = e.currentTarget;
 
              injectInlineForm(tr.parentNode.parentNode);
 
          });
 

	
 
          // inject comments into they proper positions
 
          var file_comments = $('.inline-comment-placeholder').toArray();
 
          renderInlineComments(file_comments);
 

	
 
          linkInlineComments(document.getElementsByClassName('firstlink'), document.getElementsByClassName("inline-comment"));
 

	
 
          $('#updaterevs input').change(function(e){
 
              var update = !!e.target.value;
 
              $('#pr-form-save').prop('disabled',update);
 
              $('#pr-form-clone').prop('disabled',!update);
 
          });
 
          var $org_review_members = $('#review_members').clone();
 
          $('#pr-form-reset').click(function(e){
 
              $('#pr-edit-form').hide();
 
              $('.pr-not-edit').show();
 
              $('#pr-form-save').prop('disabled',false);
 
              $('#pr-form-clone').prop('disabled',true);
 
              $('#review_members').html($org_review_members);
 
          });
 

	
 
          // hack: re-navigate to target after JS is done ... if a target is set and setting href thus won't reload
 
          if (window.location.hash != "") {
 
              window.location.href = window.location.href;
 
          }
 
      });
 
    </script>
 

	
 
</div>
 

	
0 comments (0 inline, 0 general)