repository: add check preventing of removal of repo with attached pull requests.
- fixes #5493
This commit is contained in:
parent
4c45a5dbea
commit
39d181f715
5 changed files with 54 additions and 15 deletions
|
|
@ -29,7 +29,7 @@ from rhodecode.lib import audit_logger
|
|||
from rhodecode.lib.auth import (
|
||||
LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired,
|
||||
HasRepoPermissionAny)
|
||||
from rhodecode.lib.exceptions import AttachedForksError
|
||||
from rhodecode.lib.exceptions import AttachedForksError, AttachedPullRequestsError
|
||||
from rhodecode.lib.utils2 import safe_int
|
||||
from rhodecode.lib.vcs import RepositoryError
|
||||
from rhodecode.model.db import Session, UserFollowing, User, Repository
|
||||
|
|
@ -80,22 +80,23 @@ class RepoSettingsView(RepoAppView):
|
|||
"""
|
||||
_ = self.request.translate
|
||||
handle_forks = self.request.POST.get('forks', None)
|
||||
if handle_forks == 'detach_forks':
|
||||
handle_forks = 'detach'
|
||||
elif handle_forks == 'delete_forks':
|
||||
handle_forks = 'delete'
|
||||
|
||||
try:
|
||||
_forks = self.db_repo.forks.count()
|
||||
if _forks and handle_forks:
|
||||
if handle_forks == 'detach_forks':
|
||||
handle_forks = 'detach'
|
||||
h.flash(_('Detached %s forks') % _forks, category='success')
|
||||
elif handle_forks == 'delete_forks':
|
||||
handle_forks = 'delete'
|
||||
h.flash(_('Deleted %s forks') % _forks, category='success')
|
||||
|
||||
old_data = self.db_repo.get_api_data()
|
||||
RepoModel().delete(self.db_repo, forks=handle_forks)
|
||||
|
||||
repo = audit_logger.RepoWrap(repo_id=None,
|
||||
repo_name=self.db_repo.repo_name)
|
||||
_forks = self.db_repo.forks.count()
|
||||
if _forks and handle_forks:
|
||||
if handle_forks == 'detach_forks':
|
||||
h.flash(_('Detached %s forks') % _forks, category='success')
|
||||
elif handle_forks == 'delete_forks':
|
||||
h.flash(_('Deleted %s forks') % _forks, category='success')
|
||||
|
||||
repo = audit_logger.RepoWrap(repo_id=None, repo_name=self.db_repo.repo_name)
|
||||
audit_logger.store_web(
|
||||
'repo.delete', action_data={'old_data': old_data},
|
||||
user=self._rhodecode_user, repo=repo)
|
||||
|
|
@ -118,6 +119,20 @@ class RepoSettingsView(RepoAppView):
|
|||
# redirect to advanced for forks handle action ?
|
||||
raise HTTPFound(repo_advanced_url)
|
||||
|
||||
except AttachedPullRequestsError:
|
||||
repo_advanced_url = h.route_path(
|
||||
'edit_repo_advanced', repo_name=self.db_repo_name,
|
||||
_anchor='advanced-delete')
|
||||
attached_prs = len(self.db_repo.pull_requests_source +
|
||||
self.db_repo.pull_requests_target)
|
||||
h.flash(
|
||||
_('Cannot delete `{repo}` it still contains {num} attached pull requests. '
|
||||
'Consider archiving the repository instead.').format(
|
||||
repo=self.db_repo_name, num=attached_prs), category='warning')
|
||||
|
||||
# redirect to advanced for forks handle action ?
|
||||
raise HTTPFound(repo_advanced_url)
|
||||
|
||||
except Exception:
|
||||
log.exception("Exception during deletion of repository")
|
||||
h.flash(_('An error occurred during deletion of `%s`')
|
||||
|
|
|
|||
|
|
@ -70,6 +70,10 @@ class AttachedForksError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class AttachedPullRequestsError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RepoGroupAssignmentError(Exception):
|
||||
pass
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ from zope.cachedescriptors.property import Lazy as LazyProperty
|
|||
from rhodecode import events
|
||||
from rhodecode.lib.auth import HasUserGroupPermissionAny
|
||||
from rhodecode.lib.caching_query import FromCache
|
||||
from rhodecode.lib.exceptions import AttachedForksError
|
||||
from rhodecode.lib.exceptions import AttachedForksError, AttachedPullRequestsError
|
||||
from rhodecode.lib.hooks_base import log_delete_repository
|
||||
from rhodecode.lib.user_log_filter import user_log_filter
|
||||
from rhodecode.lib.utils import make_db_config
|
||||
|
|
@ -608,7 +608,7 @@ class RepoModel(BaseModel):
|
|||
from rhodecode.lib.celerylib import tasks, run_task
|
||||
return run_task(tasks.create_repo_fork, form_data, cur_user)
|
||||
|
||||
def delete(self, repo, forks=None, fs_remove=True, cur_user=None):
|
||||
def delete(self, repo, forks=None, pull_requests=None, fs_remove=True, cur_user=None):
|
||||
"""
|
||||
Delete given repository, forks parameter defines what do do with
|
||||
attached forks. Throws AttachedForksError if deleted repo has attached
|
||||
|
|
@ -632,6 +632,12 @@ class RepoModel(BaseModel):
|
|||
elif [f for f in repo.forks]:
|
||||
raise AttachedForksError()
|
||||
|
||||
# check for pull requests
|
||||
pr_sources = repo.pull_requests_source
|
||||
pr_targets = repo.pull_requests_target
|
||||
if pull_requests != 'delete' and (pr_sources or pr_targets):
|
||||
raise AttachedPullRequestsError()
|
||||
|
||||
old_repo_dict = repo.get_dict()
|
||||
events.trigger(events.RepoPreDeleteEvent(repo))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
(_('Updated on'), h.format_date(c.rhodecode_db_repo.updated_on), '', ''),
|
||||
(_('Cached Commit id'), lambda: h.link_to(c.rhodecode_db_repo.changeset_cache.get('short_id'), h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.rhodecode_db_repo.changeset_cache.get('raw_id'))), '', ''),
|
||||
(_('Attached scoped tokens'), len(c.rhodecode_db_repo.scoped_tokens), '', [x.user for x in c.rhodecode_db_repo.scoped_tokens]),
|
||||
(_('Pull requests source'), len(c.rhodecode_db_repo.pull_requests_source), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.source_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_source]),
|
||||
(_('Pull requests target'), len(c.rhodecode_db_repo.pull_requests_target), '', ['pr_id:{}, repo:{}'.format(x.pull_request_id,x.target_repo.repo_name) for x in c.rhodecode_db_repo.pull_requests_target]),
|
||||
]
|
||||
%>
|
||||
|
||||
|
|
@ -131,6 +133,18 @@
|
|||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
<% attached_prs = len(c.rhodecode_db_repo.pull_requests_source + c.rhodecode_db_repo.pull_requests_target) %>
|
||||
% if c.rhodecode_db_repo.pull_requests_source or c.rhodecode_db_repo.pull_requests_target:
|
||||
<tr>
|
||||
<td>
|
||||
${_ungettext('This repository has %s attached pull request.', 'This repository has %s attached pull requests.', attached_prs) % attached_prs}
|
||||
<br/>
|
||||
${_('Consider to archive this repository instead.')}
|
||||
</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
% endif
|
||||
</table>
|
||||
<div style="margin: 0 0 20px 0" class="fake-space"></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ class Fixture(object):
|
|||
return r
|
||||
|
||||
def destroy_repo(self, repo_name, **kwargs):
|
||||
RepoModel().delete(repo_name, **kwargs)
|
||||
RepoModel().delete(repo_name, pull_requests='delete', **kwargs)
|
||||
Session().commit()
|
||||
|
||||
def destroy_repo_on_filesystem(self, repo_name):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue