##// END OF EJS Templates
strip: added functionality to stip choosen commits on repo settings
Bartłomiej Wołyńczyk -
r1587:6fce8671 default
parent child Browse files
Show More
@@ -1,33 +1,46 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21
22 22 def includeme(config):
23 23
24 24 config.add_route(
25 25 name='repo_maintenance',
26 26 pattern='/{repo_name:.*?[^/]}/maintenance', repo_route=True)
27 27
28 28 config.add_route(
29 29 name='repo_maintenance_execute',
30 30 pattern='/{repo_name:.*?[^/]}/maintenance/execute', repo_route=True)
31 31
32
33 # Strip
34 config.add_route(
35 name='strip',
36 pattern='/{repo_name:.*?[^/]}/strip', repo_route=True)
37
38 config.add_route(
39 name='strip_check',
40 pattern='/{repo_name:.*?[^/]}/strip_check', repo_route=True)
41
42 config.add_route(
43 name='strip_execute',
44 pattern='/{repo_name:.*?[^/]}/strip_execute', repo_route=True)
32 45 # Scan module for configuration decorators.
33 46 config.scan()
@@ -1,70 +1,110 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 21 import logging
22
23 22 from pyramid.view import view_config
24 23
25 24 from rhodecode.apps._base import RepoAppView
26 25 from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator,
27 26 NotAnonymous)
28 from rhodecode.lib import repo_maintenance
27
29 28
30 29 log = logging.getLogger(__name__)
31 30
32 31
33 class RepoMaintenanceView(RepoAppView):
32 class StripView(RepoAppView):
34 33 def load_default_context(self):
35 34 c = self._get_local_tmpl_context()
36 35
37 36 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
38 37 c.repo_info = self.db_repo
39 38
40 39 self._register_global_c(c)
41 40 return c
42 41
43 42 @LoginRequired()
44 43 @NotAnonymous()
45 44 @HasRepoPermissionAnyDecorator('repository.admin')
46 45 @view_config(
47 route_name='repo_maintenance', request_method='GET',
46 route_name='strip', request_method='GET',
48 47 renderer='rhodecode:templates/admin/repos/repo_edit.mako')
49 def repo_maintenance(self):
48 def strip(self):
50 49 c = self.load_default_context()
51 c.active = 'maintenance'
52 maintenance = repo_maintenance.RepoMaintenance()
53 c.executable_tasks = maintenance.get_tasks_for_repo(self.db_repo)
50 c.active = 'strip'
51 c.strip_limit = 10
52
54 53 return self._get_template_context(c)
55 54
56 55 @LoginRequired()
57 56 @NotAnonymous()
58 57 @HasRepoPermissionAnyDecorator('repository.admin')
59 58 @view_config(
60 route_name='repo_maintenance_execute', request_method='GET',
61 renderer='json', xhr=True)
62 def repo_maintenance_execute(self):
59 route_name='strip_check', request_method='POST',
60 renderer='json', xhr=True
61 )
62 def strip_check(self):
63 from rhodecode.lib.vcs.backends.base import EmptyCommit
64 data = {}
65 rp = self.request.POST
66 for i in range(1, 11):
67 chset = 'changeset_id-%d'%(i,)
68 check = rp.get(chset)
69 if check:
70 data[i] = self.db_repo.get_changeset(rp[chset])
71 if isinstance(data[i], EmptyCommit):
72 data[i] = {'rev': None, 'commit': rp[chset]}
73 else:
74 data[i] = {'rev': data[i].raw_id, 'branch': data[i].branch, 'author': data[i].author,
75 'comment': data[i].message}
76 else:
77 break
78 return data
79
80 @LoginRequired()
81 @NotAnonymous()
82 @HasRepoPermissionAnyDecorator('repository.admin')
83 @view_config(
84 route_name='strip_execute', request_method='POST',
85 renderer='json', xhr=True
86 )
87 def strip_execute(self):
88
89 from rhodecode.model.scm import ScmModel
90 from rhodecode.lib.ext_json import json
91
63 92 c = self.load_default_context()
64 c.active = 'maintenance'
65 _ = self.request.translate
66
67 maintenance = repo_maintenance.RepoMaintenance()
68 executed_types = maintenance.execute(self.db_repo)
69
70 return executed_types
93 user = self._rhodecode_user
94 rp = self.request.POST
95 data = {}
96 for idx in rp:
97 commit = json.loads(rp[idx])
98 #If someone put two times the same branch
99 if commit['branch'] in data.keys():
100 continue
101 try:
102 ScmModel().strip(repo=c.repo_info,
103 commit_id=commit['rev'], branch=commit['branch'])
104 log.info('Stripped commit %s from repo `%s` by %s' % (commit['rev'], c.repo_info.repo_name, user))
105 data[commit['rev']] = True
106 except Exception, e:
107 data[commit['rev']] = False
108 log.debug('Stripped commit %s from repo `%s` failed by %s, exeption %s' % (commit['rev'],
109 c.repo_info.repo_name, user, e.message))
110 return data
@@ -1,103 +1,106 b''
1 1 ## -*- coding: utf-8 -*-
2 2 ##
3 3 ## See also repo_settings.html
4 4 ##
5 5 <%inherit file="/base/base.mako"/>
6 6
7 7 <%def name="title()">
8 8 ${_('%s repository settings') % c.repo_info.repo_name}
9 9 %if c.rhodecode_name:
10 10 &middot; ${h.branding(c.rhodecode_name)}
11 11 %endif
12 12 </%def>
13 13
14 14 <%def name="breadcrumbs_links()">
15 15 ${_('Settings')}
16 16 </%def>
17 17
18 18 <%def name="menu_bar_nav()">
19 19 ${self.menu_items(active='repositories')}
20 20 </%def>
21 21
22 22 <%def name="menu_bar_subnav()">
23 23 ${self.repo_menu(active='options')}
24 24 </%def>
25 25
26 26 <%def name="main_content()">
27 27 <%include file="/admin/repos/repo_edit_${c.active}.mako"/>
28 28 </%def>
29 29
30 30
31 31 <%def name="main()">
32 32 <div class="box">
33 33 <div class="title">
34 34 ${self.repo_page_title(c.rhodecode_db_repo)}
35 35 ${self.breadcrumbs()}
36 36 </div>
37 37
38 38 <div class="sidebar-col-wrapper scw-small">
39 39 ##main
40 40 <div class="sidebar">
41 41 <ul class="nav nav-pills nav-stacked">
42 42 <li class="${'active' if c.active=='settings' else ''}">
43 43 <a href="${h.url('edit_repo', repo_name=c.repo_name)}">${_('Settings')}</a>
44 44 </li>
45 45 <li class="${'active' if c.active=='permissions' else ''}">
46 46 <a href="${h.url('edit_repo_perms', repo_name=c.repo_name)}">${_('Permissions')}</a>
47 47 </li>
48 48 <li class="${'active' if c.active=='advanced' else ''}">
49 49 <a href="${h.url('edit_repo_advanced', repo_name=c.repo_name)}">${_('Advanced')}</a>
50 50 </li>
51 51 <li class="${'active' if c.active=='vcs' else ''}">
52 52 <a href="${h.url('repo_vcs_settings', repo_name=c.repo_name)}">${_('VCS')}</a>
53 53 </li>
54 54 <li class="${'active' if c.active=='fields' else ''}">
55 55 <a href="${h.url('edit_repo_fields', repo_name=c.repo_name)}">${_('Extra Fields')}</a>
56 56 </li>
57 57 <li class="${'active' if c.active=='issuetracker' else ''}">
58 58 <a href="${h.url('repo_settings_issuetracker', repo_name=c.repo_name)}">${_('Issue Tracker')}</a>
59 59 </li>
60 60 <li class="${'active' if c.active=='caches' else ''}">
61 61 <a href="${h.url('edit_repo_caches', repo_name=c.repo_name)}">${_('Caches')}</a>
62 62 </li>
63 63 %if c.repo_info.repo_type != 'svn':
64 64 <li class="${'active' if c.active=='remote' else ''}">
65 65 <a href="${h.url('edit_repo_remote', repo_name=c.repo_name)}">${_('Remote')}</a>
66 66 </li>
67 67 %endif
68 68 <li class="${'active' if c.active=='statistics' else ''}">
69 69 <a href="${h.url('edit_repo_statistics', repo_name=c.repo_name)}">${_('Statistics')}</a>
70 70 </li>
71 71 <li class="${'active' if c.active=='integrations' else ''}">
72 72 <a href="${h.route_path('repo_integrations_home', repo_name=c.repo_name)}">${_('Integrations')}</a>
73 73 </li>
74 74 <li class="${'active' if c.active=='maintenance' else ''}">
75 75 <a href="${h.route_path('repo_maintenance', repo_name=c.repo_name)}">${_('Maintenance')}</a>
76 76 </li>
77 <li class="${'active' if c.active=='strip' else ''}">
78 <a href="${h.route_path('strip', repo_name=c.repo_name)}">${_('Strip')}</a>
79 </li>
77 80 ## TODO: dan: replace repo navigation with navlist registry like with
78 81 ## admin menu. First must find way to allow runtime configuration
79 82 ## it to account for the c.repo_info.repo_type != 'svn' call above
80 83 <%
81 84 reviewer_settings = False
82 85 try:
83 86 import rc_reviewers
84 87 reviewer_settings = True
85 88 except ImportError:
86 89 pass
87 90 %>
88 91 %if reviewer_settings:
89 92 <li class="${'active' if c.active=='reviewers' else ''}">
90 93 <a href="${h.route_path('repo_reviewers_home', repo_name=c.repo_name)}">${_('Reviewers')}</a>
91 94 </li>
92 95 %endif
93 96 </ul>
94 97 </div>
95 98
96 99 <div class="main-content-full-width">
97 100 ${self.main_content()}
98 101 </div>
99 102
100 103 </div>
101 104 </div>
102 105
103 106 </%def> No newline at end of file
@@ -1,58 +1,169 b''
1 1 <div class="panel panel-default">
2 2 <div class="panel-heading">
3 <h3 class="panel-title">${_('Maintenance')}</h3>
3 <h3 class="panel-title">${_('Strip')}</h3>
4 4 </div>
5 5 <div class="panel-body">
6 %if c.repo_info.repo_type != 'svn':
7 <p>
8 <h4>${_('Please provide up to %s commits commits to strip')%c.strip_limit}</h4>
9 </p>
10 <p>
11 ${_('In the first step commits will be verified for existance in the repository')}. </br>
12 ${_('In the second step, correct commits will be available for stripping')}.
13 </p>
14 ${h.secure_form(h.route_path('strip_check', repo_name=c.repo_info.repo_name), method='post')}
15 <div id="change_body" class="field">
16 <div id="box-1" class="inputx locked_input">
17 <input class="text" id="changeset_id-1" name="changeset_id-1" size="59"
18 placeholder="${_('Enter full 40 character commit sha')}" type="text" value="">
19 <div id = "plus_icon-1" class="btn btn-default plus_input_button">
20 <i class="icon-plus" onclick="addNew(1);return false">${_('Add another commit')}</i>
21 </div>
22 </div>
23 </div>
24 <div id="results" style="display:none; padding: 10px 0px;"></div>
25 <div class="buttons">
26 <button class="btn btn-small btn-primary" onclick="check_changsets();return false">
27 ${_('Check commits')}
28 </button>
29 </div>
30 <div id="results" style="display:none; padding: 10px 0px;"></div>
6 31
7 <p>
8 % if c.executable_tasks:
9 ${_('Perform maintenance tasks for this repo, following tasks will be performed')}:
10 <ol>
11 % for task in c.executable_tasks:
12 <li>${task}</li>
13 % endfor
14 </ol>
15 % else:
16 ${_('No maintenance tasks for this repo available')}
17 % endif
18 </p>
32 ${h.end_form()}
33 %else:
34 <p>
35 <h4>${_('Sorry this functionality is not available for SVN repository')}</h4>
36 </p>
19 37
20 <div id="results" style="display:none; padding: 10px 0px;"></div>
21 38
22 % if c.executable_tasks:
23 <div class="form">
24 <div class="fields">
25 <button class="btn btn-small btn-primary" onclick="executeTask();return false">
26 ${_('Run Maintenance')}
27 </button>
28 </div>
29 </div>
30 % endif
39 %endif
31 40
32 41 </div>
33 42 </div>
34 43
35 44
36 45 <script>
46 var plus_leaf = 1;
37 47
38 executeTask = function() {
39 var btn = $(this);
48 addNew = function(number){
49 if (number >= ${c.strip_limit}){
50 return;
51 }
52 var minus = '<i id="i_minus_icon-'+(number+1)+'" class="icon-minus" onclick="delOld('+(number+1)+');return false">${_('Remove')}</i>';
53 $('#plus_icon-'+number).detach();
54 number++;
55 var input = '<div id="box-'+number+'" class="inputx locked_input">'+
56 '<input class="text" id="changeset_id-'+number+'" name="changeset_id-'+number+'" size="59" type="text" value="">'+
57 '<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+
58 '<i id="i_plus_icon-'+(number)+'" class="icon-plus" onclick="addNew('+number+');return false">${_('Add another commit')}</i>'+
59 '</div>'+
60 '<div id="minus_icon-'+number+'" class="btn btn-default minus_input_button">'+
61 minus +
62 '</div>' +
63 '</div>';
64 $('#change_body').append(input);
65 plus_leaf++;
66 }
67
68 function re_index(number){
69 for(var i=number;i<=plus_leaf;i++){
70 var check = $('#box-'+i);
71 if (check.length == 0){
72 var change = $('#box-'+(i+1));
73
74 change.attr('id','box-'+i);
75 var plus = $('#plus_icon-'+(i+1));
76 var i_plus = $('#i_plus_icon-'+(i+1));
77 if (plus.length != 0){
78 plus.attr('id','plus_icon-'+i);
79 i_plus.attr('id','i_plus_icon-'+i);
80 i_plus.attr('onclick','addNew('+i+');return false');
81 plus_leaf--;
82 }
83 var minus = $('#minus_icon-'+(i+1));
84 var i_minus = $('#i_minus_icon-'+(i+1));
85 minus.attr('id','minus_icon-'+i);
86 i_minus.attr('id','i_minus_icon-'+i);
87 i_minus.attr('onclick','delOld('+i+');return false');
88 }
89 }
90 }
91
92 delOld = function(number){
93 $('#box-'+number).remove();
94 number = number - 1;
95 var box = $('#box-'+number);
96 var plus = '<div id="plus_icon-'+number+'" class="btn btn-default plus_input_button">'+
97 '<i id="i_plus_icon-'+number+'" class="icon-plus" onclick="addNew('+number +');return false">${_('Add another commit')}</i></div>';
98 var minus = $('#minus_icon-'+number);
99 if(number +1 == plus_leaf){
100 minus.detach();
101 box.append(plus);
102 box.append(minus);
103 }
104 re_index(number+1);
105
106 }
107
108 var result_data;
109
110 check_changsets = function() {
111 var postData = $('form').serialize();
40 112 $('#results').show();
41 $('#results').html('<h4>${_('Performing Maintenance')}...</h4>');
42
113 $('#results').html('<h4>${_('Checking commits')}...</h4>');
114 var url = "${h.route_path('strip_check', repo_name=c.repo_info.repo_name)}";
115 var btn = $('button');
43 116 btn.attr('disabled', 'disabled');
44 117 btn.addClass('disabled');
45 118
46 var url = "${h.route_path('repo_maintenance_execute', repo_name=c.repo_info.repo_name)}";
47 119 var success = function (data) {
48 var displayHtml = $('<pre></pre>');
120 result_data = {};
121 var i = 0;
122 result ='';
123 $.each(data, function(index, value){
124 i= index;
125 var box = $('#box-'+index);
126 if (value.rev){
127 result_data[index] = JSON.stringify(value);
128 msg = '${_("author")}: ' + value.author + ' ${_("comment")}: ' + value.comment;
129 result += '<h4>' +value.rev+ '${_(' commit verified positive')}</br> '+ msg + '</h4>';
130 }
131 else{
132 result += '<h4>' +value.commit+ '${_('commit verified negative')}' + '</h4>';
133 }
134 box.remove();
135 });
136 var box = $('#box-'+(parseInt(i)+1));
137 box.remove();
138 $('#results').html(result);
139 };
49 140
50 $(displayHtml).append(data);
51 $('#results').html(displayHtml);
52 btn.removeAttr('disabled');
53 btn.removeClass('disabled');
141 btn.html('Strip');
142 btn.removeAttr('disabled');
143 btn.removeClass('disabled');
144 btn.attr('onclick','strip();return false;');
145 ajaxPOST(url, postData, success, null);
146 };
147
148 strip = function(){
149 var url = "${h.route_path('strip_execute', repo_name=c.repo_info.repo_name)}";
150 var success = function(data){
151 result = '';
152 $.each(data, function(index, value){
153 if(data[index]){
154 result += '<h4>' +index+ '${_(' commit striped successful')}' + '</h4>';
155 }
156 else{
157 result += '<h4>' +index+ '${_(' commit striped failed')}' + '</h4>';
158 }
159 });
160 $('#results').html(result);
161
54 162 };
55 ajaxGET(url, success, null);
163 ajaxPOST(url, result_data, success, null);
164 var btn = $('button');
165 btn.attr('disabled', 'disabled');
166 btn.addClass('disabled');
56 167
57 }
168 };
58 169 </script>
General Comments 0
You need to be logged in to leave comments. Login now