##// END OF EJS Templates
pull request: select 'tip' by default ... and show what it means right now
pull request: select 'tip' by default ... and show what it means right now

File last commit:

r3323:a0729656 beta
r3329:f8c55b48 beta
Show More
pull_request.py
252 lines | 9.3 KiB | text/x-python | PythonLexer
Added basic models for saving open pull requests...
r2434 # -*- coding: utf-8 -*-
"""
Added option to close pull requests, in future that will be close & merge
r2608 rhodecode.model.pull_request
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Added basic models for saving open pull requests...
r2434
pull request model for RhodeCode
:created_on: Jun 6, 2012
:author: marcink
:copyright: (C) 2012-2012 Marcin Kuzminski <marcin@python-works.com>
:license: GPLv3, see COPYING for more details.
"""
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
Added option to close pull requests, in future that will be close & merge
r2608 import datetime
Enabled compare engine for tags...
r3010 import re
Switch to waitress wsgi server by default in rhodecode....
r2597
Added basic models for saving open pull requests...
r2434 from pylons.i18n.translation import _
Switch to waitress wsgi server by default in rhodecode....
r2597 from rhodecode.model.meta import Session
Mads Kiilerich
pull request: use unionrepo instead of outgoing...
r3303 from rhodecode.lib import helpers as h, unionrepo
Added basic models for saving open pull requests...
r2434 from rhodecode.model import BaseModel
set the status of changesets initially on pull request, and make sure we care of version collisions....
r3175 from rhodecode.model.db import PullRequest, PullRequestReviewers, Notification,\
ChangesetStatus
Added basic models for saving open pull requests...
r2434 from rhodecode.model.notification import NotificationModel
from rhodecode.lib.utils2 import safe_unicode
Mads Kiilerich
pull request: use unionrepo instead of outgoing...
r3303 from rhodecode.lib.vcs.utils.hgcompat import scmutil
Mads Kiilerich
pull requeset: move stuff around, preparing for next change...
r3301 from rhodecode.lib.vcs.utils import safe_str
small refactoring, moved shared for diff generation of code into pull-request model
r2442
Added basic models for saving open pull requests...
r2434 log = logging.getLogger(__name__)
class PullRequestModel(BaseModel):
Added associated classes into child models
r2522 cls = PullRequest
Added option to close pull requests, in future that will be close & merge
r2608 def __get_pull_request(self, pull_request):
return self._get_instance(PullRequest, pull_request)
- pull request generates overview based on it's params...
r2440 def get_all(self, repo):
repo = self._get_repo(repo)
fix order of pull-requests in show all page
r3262 return PullRequest.query()\
.filter(PullRequest.other_repo == repo)\
.order_by(PullRequest.created_on)\
.all()
- pull request generates overview based on it's params...
r2440
set the status of changesets initially on pull request, and make sure we care of version collisions....
r3175 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
Added dynamic data loading for other repo we open pull request against...
r2541
- pull request generates overview based on it's params...
r2440 created_by_user = self._get_user(created_by)
Added dynamic data loading for other repo we open pull request against...
r2541 org_repo = self._get_repo(org_repo)
other_repo = self._get_repo(other_repo)
Added basic models for saving open pull requests...
r2434
new = PullRequest()
Added dynamic data loading for other repo we open pull request against...
r2541 new.org_repo = org_repo
Added basic models for saving open pull requests...
r2434 new.org_ref = org_ref
Added dynamic data loading for other repo we open pull request against...
r2541 new.other_repo = other_repo
Added basic models for saving open pull requests...
r2434 new.other_ref = other_ref
new.revisions = revisions
new.title = title
new.description = description
- pull request generates overview based on it's params...
r2440 new.author = created_by_user
Added basic models for saving open pull requests...
r2434 self.sa.add(new)
Added dynamic data loading for other repo we open pull request against...
r2541 Session().flush()
Added basic models for saving open pull requests...
r2434 #members
for member in reviewers:
_usr = self._get_user(member)
reviewer = PullRequestReviewers(_usr, new)
self.sa.add(reviewer)
set the status of changesets initially on pull request, and make sure we care of version collisions....
r3175 #reset state to under-review
ChangesetStatusModel().set_status(
repo=org_repo,
status=ChangesetStatus.STATUS_UNDER_REVIEW,
user=created_by_user,
pull_request=new
)
Added basic models for saving open pull requests...
r2434 #notification to reviewers
notif = NotificationModel()
- pull request generates overview based on it's params...
r2440
Nicer email notifications about pull-request
r2799 pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name,
pull_request_id=new.pull_request_id,
qualified=True,
)
Added basic models for saving open pull requests...
r2434 subject = safe_unicode(
h.link_to(
Mads Kiilerich
pull request: mention title of pull request in notifications
r3251 _('%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s') % \
Added basic models for saving open pull requests...
r2434 {'user': created_by_user.username,
Mads Kiilerich
pull request: mention title of pull request in notifications
r3251 'pr_title': new.title,
Added basic models for saving open pull requests...
r2434 'pr_id': new.pull_request_id},
Nicer email notifications about pull-request
r2799 pr_url
Added basic models for saving open pull requests...
r2434 )
)
body = description
Nicer email notifications about pull-request
r2799 kwargs = {
'pr_title': title,
'pr_user_created': h.person(created_by_user.email),
'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name,
qualified=True,),
'pr_url': pr_url,
'pr_revisions': revisions
}
Added dynamic data loading for other repo we open pull request against...
r2541 notif.create(created_by=created_by_user, subject=subject, body=body,
Added basic models for saving open pull requests...
r2434 recipients=reviewers,
Nicer email notifications about pull-request
r2799 type_=Notification.TYPE_PULL_REQUEST, email_kwargs=kwargs)
Added basic models for saving open pull requests...
r2434 return new
small refactoring, moved shared for diff generation of code into pull-request model
r2442
Added editing of pull-request reviewers.
r2614 def update_reviewers(self, pull_request, reviewers_ids):
reviewers_ids = set(reviewers_ids)
pull_request = self.__get_pull_request(pull_request)
current_reviewers = PullRequestReviewers.query()\
.filter(PullRequestReviewers.pull_request==
pull_request)\
.all()
current_reviewers_ids = set([x.user.user_id for x in current_reviewers])
to_add = reviewers_ids.difference(current_reviewers_ids)
to_remove = current_reviewers_ids.difference(reviewers_ids)
log.debug("Adding %s reviewers" % to_add)
log.debug("Removing %s reviewers" % to_remove)
for uid in to_add:
_usr = self._get_user(uid)
reviewer = PullRequestReviewers(_usr, pull_request)
self.sa.add(reviewer)
for uid in to_remove:
reviewer = PullRequestReviewers.query()\
.filter(PullRequestReviewers.user_id==uid,
PullRequestReviewers.pull_request==pull_request)\
.scalar()
if reviewer:
self.sa.delete(reviewer)
Authors of pull-requests can now delete them
r2746 def delete(self, pull_request):
pull_request = self.__get_pull_request(pull_request)
Session().delete(pull_request)
Added option to close pull requests, in future that will be close & merge
r2608 def close_pull_request(self, pull_request):
pull_request = self.__get_pull_request(pull_request)
pull_request.status = PullRequest.STATUS_CLOSED
pull_request.updated_on = datetime.datetime.now()
self.sa.add(pull_request)
Mads Kiilerich
refactoring: drop unused 'discovery data' in pull request and compare diffs
r3192 def _get_changesets(self, alias, org_repo, org_ref, other_repo, other_ref):
small refactoring, moved shared for diff generation of code into pull-request model
r2442 """
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 Returns a list of changesets that can be merged from org_repo@org_ref
to other_repo@other_ref ... and the ancestor that would be used for merge
small refactoring, moved shared for diff generation of code into pull-request model
r2442
:param org_repo:
:param org_ref:
:param other_repo:
:param other_ref:
:param tmp:
"""
Basic implementation of cherry picking changesets...
r3023
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 ancestor = None
Basic implementation of cherry picking changesets...
r3023
Mads Kiilerich
pull request: shuffle different-repo and hg-git conditionals around, no code change
r3300 if alias == 'hg':
Mads Kiilerich
pull requeset: move stuff around, preparing for next change...
r3301 # lookup up the exact node id
_revset_predicates = {
'branch': 'branch',
'book': 'bookmark',
'tag': 'tag',
'rev': 'id',
}
org_rev_spec = "%s('%s')" % (_revset_predicates[org_ref[0]],
safe_str(org_ref[1]))
org_rev = scmutil.revsingle(org_repo._repo,
org_rev_spec)
other_rev_spec = "%s('%s')" % (_revset_predicates[other_ref[0]],
safe_str(other_ref[1]))
other_rev = scmutil.revsingle(other_repo._repo, other_rev_spec)
small refactoring, moved shared for diff generation of code into pull-request model
r2442
Mads Kiilerich
pull request: shuffle different-repo and hg-git conditionals around, no code change
r3300 #case two independent repos
if org_repo != other_repo:
Mads Kiilerich
compare: swap org and other when they refer to different repos, ie are pull request style...
r3322 hgrepo = unionrepo.unionrepository(other_repo.baseui,
other_repo.path,
org_repo.path)
# all the changesets we are looking for will be in other_repo,
# so rev numbers from hgrepo can be used in other_repo
Mads Kiilerich
pull request: shuffle different-repo and hg-git conditionals around, no code change
r3300
Enabled compare engine for tags...
r3010 #no remote compare do it on the same repository
Mads Kiilerich
pull request: shuffle different-repo and hg-git conditionals around, no code change
r3300 else:
Mads Kiilerich
compare: swap org and other when they refer to different repos, ie are pull request style...
r3322 hgrepo = other_repo._repo
whitespace cleanup
r3315
Mads Kiilerich
compare: swap org and other when they refer to different repos, ie are pull request style...
r3322 revs = ["ancestors(id('%s')) and not ancestors(id('%s'))" %
(other_rev, org_rev)]
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 changesets = [other_repo.get_changeset(cs)
for cs in scmutil.revrange(hgrepo, revs)]
if org_repo != other_repo:
ancestors = scmutil.revrange(hgrepo,
["ancestor(id('%s'), id('%s'))" % (org_rev, other_rev)])
if len(ancestors) == 1:
ancestor = hgrepo[ancestors[0]].hex()
Mads Kiilerich
pull request: shuffle different-repo and hg-git conditionals around, no code change
r3300
elif alias == 'git':
assert org_repo == other_repo, (org_repo, other_repo) # no git support for different repos
so, se = org_repo.run_git_command(
'log --reverse --pretty="format: %%H" -s -p %s..%s' % (org_ref[1],
other_ref[1])
)
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 changesets = [org_repo.get_changeset(cs)
for cs in re.findall(r'[0-9a-fA-F]{40}', so)]
small refactoring, moved shared for diff generation of code into pull-request model
r2442
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 return changesets, ancestor
small refactoring, moved shared for diff generation of code into pull-request model
r2442
def get_compare_data(self, org_repo, org_ref, other_repo, other_ref):
"""
Mads Kiilerich
pull requeset: move stuff around, preparing for next change...
r3301 Returns incoming changesets for mercurial repositories
small refactoring, moved shared for diff generation of code into pull-request model
r2442
:param org_repo:
:type org_repo:
:param org_ref:
:type org_ref:
:param other_repo:
:type other_repo:
:param other_ref:
:type other_ref:
"""
if len(org_ref) != 2 or not isinstance(org_ref, (list, tuple)):
raise Exception('org_ref must be a two element list/tuple')
if len(other_ref) != 2 or not isinstance(org_ref, (list, tuple)):
raise Exception('other_ref must be a two element list/tuple')
Enabled compare engine for tags...
r3010 org_repo_scm = org_repo.scm_instance
other_repo_scm = other_repo.scm_instance
alias = org_repo.scm_instance.alias
Mads Kiilerich
compare: show aggregated diff of what will be merged to other repo, using merge ancestor...
r3323 cs_ranges, ancestor = self._get_changesets(alias,
org_repo_scm, org_ref,
other_repo_scm, other_ref)
return cs_ranges, ancestor