Show More
@@ -29,5 +29,18 b' def includeme(config):' | |||
|
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() |
@@ -19,18 +19,17 b'' | |||
|
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 |
|
|
32 | class StripView(RepoAppView): | |
|
34 | 33 | def load_default_context(self): |
|
35 | 34 | c = self._get_local_tmpl_context() |
|
36 | 35 | |
@@ -44,27 +43,68 b' class RepoMaintenanceView(RepoAppView):' | |||
|
44 | 43 | @NotAnonymous() |
|
45 | 44 | @HasRepoPermissionAnyDecorator('repository.admin') |
|
46 | 45 | @view_config( |
|
47 |
route_name=' |
|
|
46 | route_name='strip', request_method='GET', | |
|
48 | 47 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') |
|
49 |
def |
|
|
48 | def strip(self): | |
|
50 | 49 | c = self.load_default_context() |
|
51 |
c.active = ' |
|
|
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=' |
|
|
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 |
|
|
|
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 |
@@ -74,6 +74,9 b'' | |||
|
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 |
@@ -1,32 +1,41 b'' | |||
|
1 | 1 | <div class="panel panel-default"> |
|
2 | 2 | <div class="panel-heading"> |
|
3 |
<h3 class="panel-title">${_(' |
|
|
3 | <h3 class="panel-title">${_('Strip')}</h3> | |
|
4 | 4 | </div> |
|
5 | 5 | <div class="panel-body"> |
|
6 | ||
|
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> | |
|
7 | 10 | <p> |
|
8 | % if c.executable_tasks: | |
|
9 | ${_('Perform maintenance tasks for this repo, following tasks will be performed')}: | |
|
10 |
< |
|
|
11 | % for task in c.executable_tasks: | |
|
12 | <li>${task}</li> | |
|
13 | % endfor | |
|
14 | </ol> | |
|
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> | |
|
31 | ||
|
32 | ${h.end_form()} | |
|
15 | 33 |
|
|
16 | ${_('No maintenance tasks for this repo available')} | |
|
17 | % endif | |
|
34 | <p> | |
|
35 | <h4>${_('Sorry this functionality is not available for SVN repository')}</h4> | |
|
18 | 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 | 39 |
|
|
31 | 40 | |
|
32 | 41 | </div> |
@@ -34,25 +43,127 b'' | |||
|
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>${_(' |
|
|
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); | |
|
141 | btn.html('Strip'); | |
|
52 | 142 |
|
|
53 | 143 |
|
|
144 | btn.attr('onclick','strip();return false;'); | |
|
145 | ajaxPOST(url, postData, success, null); | |
|
54 | 146 | }; |
|
55 | ajaxGET(url, success, null); | |
|
56 | 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>'; | |
|
57 | 155 | } |
|
156 | else{ | |
|
157 | result += '<h4>' +index+ '${_(' commit striped failed')}' + '</h4>'; | |
|
158 | } | |
|
159 | }); | |
|
160 | $('#results').html(result); | |
|
161 | ||
|
162 | }; | |
|
163 | ajaxPOST(url, result_data, success, null); | |
|
164 | var btn = $('button'); | |
|
165 | btn.attr('disabled', 'disabled'); | |
|
166 | btn.addClass('disabled'); | |
|
167 | ||
|
168 | }; | |
|
58 | 169 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now