strip: added functionality to stip choosen commits on repo settings
This commit is contained in:
parent
93bb2a8b36
commit
57f66c793e
4 changed files with 295 additions and 0 deletions
|
|
@ -29,5 +29,18 @@ def includeme(config):
|
|||
name='repo_maintenance_execute',
|
||||
pattern='/{repo_name:.*?[^/]}/maintenance/execute', repo_route=True)
|
||||
|
||||
|
||||
# Strip
|
||||
config.add_route(
|
||||
name='strip',
|
||||
pattern='/{repo_name:.*?[^/]}/strip', repo_route=True)
|
||||
|
||||
config.add_route(
|
||||
name='strip_check',
|
||||
pattern='/{repo_name:.*?[^/]}/strip_check', repo_route=True)
|
||||
|
||||
config.add_route(
|
||||
name='strip_execute',
|
||||
pattern='/{repo_name:.*?[^/]}/strip_execute', repo_route=True)
|
||||
# Scan module for configuration decorators.
|
||||
config.scan()
|
||||
|
|
|
|||
110
rhodecode/apps/repository/views/strip.py
Normal file
110
rhodecode/apps/repository/views/strip.py
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2011-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
# (only), as published by the Free Software Foundation.
|
||||
#
|
||||
# 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 Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import logging
|
||||
from pyramid.view import view_config
|
||||
|
||||
from rhodecode.apps._base import RepoAppView
|
||||
from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator,
|
||||
NotAnonymous)
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class StripView(RepoAppView):
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
|
||||
# TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
|
||||
c.repo_info = self.db_repo
|
||||
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
@view_config(
|
||||
route_name='strip', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/repos/repo_edit.mako')
|
||||
def strip(self):
|
||||
c = self.load_default_context()
|
||||
c.active = 'strip'
|
||||
c.strip_limit = 10
|
||||
|
||||
return self._get_template_context(c)
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
@view_config(
|
||||
route_name='strip_check', request_method='POST',
|
||||
renderer='json', xhr=True
|
||||
)
|
||||
def strip_check(self):
|
||||
from rhodecode.lib.vcs.backends.base import EmptyCommit
|
||||
data = {}
|
||||
rp = self.request.POST
|
||||
for i in range(1, 11):
|
||||
chset = 'changeset_id-%d'%(i,)
|
||||
check = rp.get(chset)
|
||||
if check:
|
||||
data[i] = self.db_repo.get_changeset(rp[chset])
|
||||
if isinstance(data[i], EmptyCommit):
|
||||
data[i] = {'rev': None, 'commit': rp[chset]}
|
||||
else:
|
||||
data[i] = {'rev': data[i].raw_id, 'branch': data[i].branch, 'author': data[i].author,
|
||||
'comment': data[i].message}
|
||||
else:
|
||||
break
|
||||
return data
|
||||
|
||||
@LoginRequired()
|
||||
@NotAnonymous()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
@view_config(
|
||||
route_name='strip_execute', request_method='POST',
|
||||
renderer='json', xhr=True
|
||||
)
|
||||
def strip_execute(self):
|
||||
|
||||
from rhodecode.model.scm import ScmModel
|
||||
from rhodecode.lib.ext_json import json
|
||||
|
||||
c = self.load_default_context()
|
||||
user = self._rhodecode_user
|
||||
rp = self.request.POST
|
||||
data = {}
|
||||
for idx in rp:
|
||||
commit = json.loads(rp[idx])
|
||||
#If someone put two times the same branch
|
||||
if commit['branch'] in data.keys():
|
||||
continue
|
||||
try:
|
||||
ScmModel().strip(repo=c.repo_info,
|
||||
commit_id=commit['rev'], branch=commit['branch'])
|
||||
log.info('Stripped commit %s from repo `%s` by %s' % (commit['rev'], c.repo_info.repo_name, user))
|
||||
data[commit['rev']] = True
|
||||
except Exception, e:
|
||||
data[commit['rev']] = False
|
||||
log.debug('Stripped commit %s from repo `%s` failed by %s, exeption %s' % (commit['rev'],
|
||||
c.repo_info.repo_name, user, e.message))
|
||||
return data
|
||||
|
|
@ -74,6 +74,9 @@
|
|||
<li class="${'active' if c.active=='maintenance' else ''}">
|
||||
<a href="${h.route_path('repo_maintenance', repo_name=c.repo_name)}">${_('Maintenance')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='strip' else ''}">
|
||||
<a href="${h.route_path('strip', repo_name=c.repo_name)}">${_('Strip')}</a>
|
||||
</li>
|
||||
## TODO: dan: replace repo navigation with navlist registry like with
|
||||
## admin menu. First must find way to allow runtime configuration
|
||||
## it to account for the c.repo_info.repo_type != 'svn' call above
|
||||
|
|
|
|||
169
rhodecode/templates/admin/repos/repo_edit_strip.mako
Normal file
169
rhodecode/templates/admin/repos/repo_edit_strip.mako
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('Strip')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
%if c.repo_info.repo_type != 'svn':
|
||||
<p>
|
||||
<h4>${_('Please provide up to %s commits commits to strip')%c.strip_limit}</h4>
|
||||
</p>
|
||||
<p>
|
||||
${_('In the first step commits will be verified for existance in the repository')}. </br>
|
||||
${_('In the second step, correct commits will be available for stripping')}.
|
||||
</p>
|
||||
${h.secure_form(h.route_path('strip_check', repo_name=c.repo_info.repo_name), method='post')}
|
||||
<div id="change_body" class="field">
|
||||
<div id="box-1" class="inputx locked_input">
|
||||
<input class="text" id="changeset_id-1" name="changeset_id-1" size="59"
|
||||
placeholder="${_('Enter full 40 character commit sha')}" type="text" value="">
|
||||
<div id = "plus_icon-1" class="btn btn-default plus_input_button">
|
||||
<i class="icon-plus" onclick="addNew(1);return false">${_('Add another commit')}</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="results" style="display:none; padding: 10px 0px;"></div>
|
||||
<div class="buttons">
|
||||
<button class="btn btn-small btn-primary" onclick="check_changsets();return false">
|
||||
${_('Check commits')}
|
||||
</button>
|
||||
</div>
|
||||
<div id="results" style="display:none; padding: 10px 0px;"></div>
|
||||
|
||||
${h.end_form()}
|
||||
%else:
|
||||
<p>
|
||||
<h4>${_('Sorry this functionality is not available for SVN repository')}</h4>
|
||||
</p>
|
||||
|
||||
|
||||
%endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
var plus_leaf = 1;
|
||||
|
||||
addNew = function(number){
|
||||
if (number >= ${c.strip_limit}){
|
||||
return;
|
||||
}
|
||||
var minus = '<i id="i_minus_icon-'+(number+1)+'" class="icon-minus" onclick="delOld('+(number+1)+');return false">${_('Remove')}</i>';
|
||||
$('#plus_icon-'+number).detach();
|
||||
number++;
|
||||
var input = '<div id="box-'+number+'" class="inputx locked_input">'+
|
||||
'<input class="text" id="changeset_id-'+number+'" name="changeset_id-'+number+'" size="59" type="text" value="">'+
|
||||
'<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+
|
||||
'<i id="i_plus_icon-'+(number)+'" class="icon-plus" onclick="addNew('+number+');return false">${_('Add another commit')}</i>'+
|
||||
'</div>'+
|
||||
'<div id="minus_icon-'+number+'" class="btn btn-default minus_input_button">'+
|
||||
minus +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
$('#change_body').append(input);
|
||||
plus_leaf++;
|
||||
}
|
||||
|
||||
function re_index(number){
|
||||
for(var i=number;i<=plus_leaf;i++){
|
||||
var check = $('#box-'+i);
|
||||
if (check.length == 0){
|
||||
var change = $('#box-'+(i+1));
|
||||
|
||||
change.attr('id','box-'+i);
|
||||
var plus = $('#plus_icon-'+(i+1));
|
||||
var i_plus = $('#i_plus_icon-'+(i+1));
|
||||
if (plus.length != 0){
|
||||
plus.attr('id','plus_icon-'+i);
|
||||
i_plus.attr('id','i_plus_icon-'+i);
|
||||
i_plus.attr('onclick','addNew('+i+');return false');
|
||||
plus_leaf--;
|
||||
}
|
||||
var minus = $('#minus_icon-'+(i+1));
|
||||
var i_minus = $('#i_minus_icon-'+(i+1));
|
||||
minus.attr('id','minus_icon-'+i);
|
||||
i_minus.attr('id','i_minus_icon-'+i);
|
||||
i_minus.attr('onclick','delOld('+i+');return false');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delOld = function(number){
|
||||
$('#box-'+number).remove();
|
||||
number = number - 1;
|
||||
var box = $('#box-'+number);
|
||||
var plus = '<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+
|
||||
'<i id="i_plus_icon-'+number+'" class="icon-plus" onclick="addNew('+number +');return false">${_('Add another commit')}</i></div>';
|
||||
var minus = $('#minus_icon-'+number);
|
||||
if(number +1 == plus_leaf){
|
||||
minus.detach();
|
||||
box.append(plus);
|
||||
box.append(minus);
|
||||
}
|
||||
re_index(number+1);
|
||||
|
||||
}
|
||||
|
||||
var result_data;
|
||||
|
||||
check_changsets = function() {
|
||||
var postData = $('form').serialize();
|
||||
$('#results').show();
|
||||
$('#results').html('<h4>${_('Checking commits')}...</h4>');
|
||||
var url = "${h.route_path('strip_check', repo_name=c.repo_info.repo_name)}";
|
||||
var btn = $('button');
|
||||
btn.attr('disabled', 'disabled');
|
||||
btn.addClass('disabled');
|
||||
|
||||
var success = function (data) {
|
||||
result_data = {};
|
||||
var i = 0;
|
||||
result ='';
|
||||
$.each(data, function(index, value){
|
||||
i= index;
|
||||
var box = $('#box-'+index);
|
||||
if (value.rev){
|
||||
result_data[index] = JSON.stringify(value);
|
||||
msg = '${_("author")}: ' + value.author + ' ${_("comment")}: ' + value.comment;
|
||||
result += '<h4>' +value.rev+ '${_(' commit verified positive')}</br> '+ msg + '</h4>';
|
||||
}
|
||||
else{
|
||||
result += '<h4>' +value.commit+ '${_('commit verified negative')}' + '</h4>';
|
||||
}
|
||||
box.remove();
|
||||
});
|
||||
var box = $('#box-'+(parseInt(i)+1));
|
||||
box.remove();
|
||||
$('#results').html(result);
|
||||
};
|
||||
|
||||
btn.html('Strip');
|
||||
btn.removeAttr('disabled');
|
||||
btn.removeClass('disabled');
|
||||
btn.attr('onclick','strip();return false;');
|
||||
ajaxPOST(url, postData, success, null);
|
||||
};
|
||||
|
||||
strip = function(){
|
||||
var url = "${h.route_path('strip_execute', repo_name=c.repo_info.repo_name)}";
|
||||
var success = function(data){
|
||||
result = '';
|
||||
$.each(data, function(index, value){
|
||||
if(data[index]){
|
||||
result += '<h4>' +index+ '${_(' commit striped successful')}' + '</h4>';
|
||||
}
|
||||
else{
|
||||
result += '<h4>' +index+ '${_(' commit striped failed')}' + '</h4>';
|
||||
}
|
||||
});
|
||||
$('#results').html(result);
|
||||
|
||||
};
|
||||
ajaxPOST(url, result_data, success, null);
|
||||
var btn = $('button');
|
||||
btn.attr('disabled', 'disabled');
|
||||
btn.addClass('disabled');
|
||||
|
||||
};
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue