Mercurial > hg > soundsoftware-site
comparison .svn/pristine/ae/ae9b39171caeb6f8f6a13fdb73ccbb11ad433254.svn-base @ 1295:622f24f53b42 redmine-2.3
Update to Redmine SVN revision 11972 on 2.3-stable branch
author | Chris Cannam |
---|---|
date | Fri, 14 Jun 2013 09:02:21 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1294:3e4c3460b6ca | 1295:622f24f53b42 |
---|---|
1 # encoding: utf-8 | |
2 # | |
3 # Redmine - project management software | |
4 # Copyright (C) 2006-2012 Jean-Philippe Lang | |
5 # | |
6 # This program is free software; you can redistribute it and/or | |
7 # modify it under the terms of the GNU General Public License | |
8 # as published by the Free Software Foundation; either version 2 | |
9 # of the License, or (at your option) any later version. | |
10 # | |
11 # This program is distributed in the hope that it will be useful, | |
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 # GNU General Public License for more details. | |
15 # | |
16 # You should have received a copy of the GNU General Public License | |
17 # along with this program; if not, write to the Free Software | |
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | |
20 module RepositoriesHelper | |
21 def format_revision(revision) | |
22 if revision.respond_to? :format_identifier | |
23 revision.format_identifier | |
24 else | |
25 revision.to_s | |
26 end | |
27 end | |
28 | |
29 def truncate_at_line_break(text, length = 255) | |
30 if text | |
31 text.gsub(%r{^(.{#{length}}[^\n]*)\n.+$}m, '\\1...') | |
32 end | |
33 end | |
34 | |
35 def render_properties(properties) | |
36 unless properties.nil? || properties.empty? | |
37 content = '' | |
38 properties.keys.sort.each do |property| | |
39 content << content_tag('li', "<b>#{h property}</b>: <span>#{h properties[property]}</span>".html_safe) | |
40 end | |
41 content_tag('ul', content.html_safe, :class => 'properties') | |
42 end | |
43 end | |
44 | |
45 def render_changeset_changes | |
46 changes = @changeset.filechanges.find(:all, :limit => 1000, :order => 'path').collect do |change| | |
47 case change.action | |
48 when 'A' | |
49 # Detects moved/copied files | |
50 if !change.from_path.blank? | |
51 change.action = | |
52 @changeset.filechanges.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C' | |
53 end | |
54 change | |
55 when 'D' | |
56 @changeset.filechanges.detect {|c| c.from_path == change.path} ? nil : change | |
57 else | |
58 change | |
59 end | |
60 end.compact | |
61 | |
62 tree = { } | |
63 changes.each do |change| | |
64 p = tree | |
65 dirs = change.path.to_s.split('/').select {|d| !d.blank?} | |
66 path = '' | |
67 dirs.each do |dir| | |
68 path += '/' + dir | |
69 p[:s] ||= {} | |
70 p = p[:s] | |
71 p[path] ||= {} | |
72 p = p[path] | |
73 end | |
74 p[:c] = change | |
75 end | |
76 render_changes_tree(tree[:s]) | |
77 end | |
78 | |
79 def render_changes_tree(tree) | |
80 return '' if tree.nil? | |
81 output = '' | |
82 output << '<ul>' | |
83 tree.keys.sort.each do |file| | |
84 style = 'change' | |
85 text = File.basename(h(file)) | |
86 if s = tree[file][:s] | |
87 style << ' folder' | |
88 path_param = to_path_param(@repository.relative_path(file)) | |
89 text = link_to(h(text), :controller => 'repositories', | |
90 :action => 'show', | |
91 :id => @project, | |
92 :repository_id => @repository.identifier_param, | |
93 :path => path_param, | |
94 :rev => @changeset.identifier) | |
95 output << "<li class='#{style}'>#{text}" | |
96 output << render_changes_tree(s) | |
97 output << "</li>" | |
98 elsif c = tree[file][:c] | |
99 style << " change-#{c.action}" | |
100 path_param = to_path_param(@repository.relative_path(c.path)) | |
101 text = link_to(h(text), :controller => 'repositories', | |
102 :action => 'entry', | |
103 :id => @project, | |
104 :repository_id => @repository.identifier_param, | |
105 :path => path_param, | |
106 :rev => @changeset.identifier) unless c.action == 'D' | |
107 text << " - #{h(c.revision)}" unless c.revision.blank? | |
108 text << ' ('.html_safe + link_to(l(:label_diff), :controller => 'repositories', | |
109 :action => 'diff', | |
110 :id => @project, | |
111 :repository_id => @repository.identifier_param, | |
112 :path => path_param, | |
113 :rev => @changeset.identifier) + ') '.html_safe if c.action == 'M' | |
114 text << ' '.html_safe + content_tag('span', h(c.from_path), :class => 'copied-from') unless c.from_path.blank? | |
115 output << "<li class='#{style}'>#{text}</li>" | |
116 end | |
117 end | |
118 output << '</ul>' | |
119 output.html_safe | |
120 end | |
121 | |
122 def repository_field_tags(form, repository) | |
123 method = repository.class.name.demodulize.underscore + "_field_tags" | |
124 if repository.is_a?(Repository) && | |
125 respond_to?(method) && method != 'repository_field_tags' | |
126 send(method, form, repository) | |
127 end | |
128 end | |
129 | |
130 def scm_select_tag(repository) | |
131 scm_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']] | |
132 Redmine::Scm::Base.all.each do |scm| | |
133 if Setting.enabled_scm.include?(scm) || | |
134 (repository && repository.class.name.demodulize == scm) | |
135 scm_options << ["Repository::#{scm}".constantize.scm_name, scm] | |
136 end | |
137 end | |
138 select_tag('repository_scm', | |
139 options_for_select(scm_options, repository.class.name.demodulize), | |
140 :disabled => (repository && !repository.new_record?), | |
141 :data => {:remote => true, :method => 'get'}) | |
142 end | |
143 | |
144 def with_leading_slash(path) | |
145 path.to_s.starts_with?('/') ? path : "/#{path}" | |
146 end | |
147 | |
148 def without_leading_slash(path) | |
149 path.gsub(%r{^/+}, '') | |
150 end | |
151 | |
152 def subversion_field_tags(form, repository) | |
153 content_tag('p', form.text_field(:url, :size => 60, :required => true, | |
154 :disabled => !repository.safe_attribute?('url')) + | |
155 '<br />'.html_safe + | |
156 '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') + | |
157 content_tag('p', form.text_field(:login, :size => 30)) + | |
158 content_tag('p', form.password_field( | |
159 :password, :size => 30, :name => 'ignore', | |
160 :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)), | |
161 :onfocus => "this.value=''; this.name='repository[password]';", | |
162 :onchange => "this.name='repository[password]';")) | |
163 end | |
164 | |
165 def darcs_field_tags(form, repository) | |
166 content_tag('p', form.text_field( | |
167 :url, :label => l(:field_path_to_repository), | |
168 :size => 60, :required => true, | |
169 :disabled => !repository.safe_attribute?('url'))) + | |
170 content_tag('p', form.select( | |
171 :log_encoding, [nil] + Setting::ENCODINGS, | |
172 :label => l(:field_commit_logs_encoding), :required => true)) | |
173 end | |
174 | |
175 def mercurial_field_tags(form, repository) | |
176 content_tag('p', form.text_field( | |
177 :url, :label => l(:field_path_to_repository), | |
178 :size => 60, :required => true, | |
179 :disabled => !repository.safe_attribute?('url') | |
180 ) + | |
181 '<br />'.html_safe + l(:text_mercurial_repository_note)) + | |
182 content_tag('p', form.select( | |
183 :path_encoding, [nil] + Setting::ENCODINGS, | |
184 :label => l(:field_scm_path_encoding) | |
185 ) + | |
186 '<br />'.html_safe + l(:text_scm_path_encoding_note)) | |
187 end | |
188 | |
189 def git_field_tags(form, repository) | |
190 content_tag('p', form.text_field( | |
191 :url, :label => l(:field_path_to_repository), | |
192 :size => 60, :required => true, | |
193 :disabled => !repository.safe_attribute?('url') | |
194 ) + | |
195 '<br />'.html_safe + | |
196 l(:text_git_repository_note)) + | |
197 content_tag('p', form.select( | |
198 :path_encoding, [nil] + Setting::ENCODINGS, | |
199 :label => l(:field_scm_path_encoding) | |
200 ) + | |
201 '<br />'.html_safe + l(:text_scm_path_encoding_note)) + | |
202 content_tag('p', form.check_box( | |
203 :extra_report_last_commit, | |
204 :label => l(:label_git_report_last_commit) | |
205 )) | |
206 end | |
207 | |
208 def cvs_field_tags(form, repository) | |
209 content_tag('p', form.text_field( | |
210 :root_url, | |
211 :label => l(:field_cvsroot), | |
212 :size => 60, :required => true, | |
213 :disabled => !repository.safe_attribute?('root_url'))) + | |
214 content_tag('p', form.text_field( | |
215 :url, | |
216 :label => l(:field_cvs_module), | |
217 :size => 30, :required => true, | |
218 :disabled => !repository.safe_attribute?('url'))) + | |
219 content_tag('p', form.select( | |
220 :log_encoding, [nil] + Setting::ENCODINGS, | |
221 :label => l(:field_commit_logs_encoding), :required => true)) + | |
222 content_tag('p', form.select( | |
223 :path_encoding, [nil] + Setting::ENCODINGS, | |
224 :label => l(:field_scm_path_encoding) | |
225 ) + | |
226 '<br />'.html_safe + l(:text_scm_path_encoding_note)) | |
227 end | |
228 | |
229 def bazaar_field_tags(form, repository) | |
230 content_tag('p', form.text_field( | |
231 :url, :label => l(:field_path_to_repository), | |
232 :size => 60, :required => true, | |
233 :disabled => !repository.safe_attribute?('url'))) + | |
234 content_tag('p', form.select( | |
235 :log_encoding, [nil] + Setting::ENCODINGS, | |
236 :label => l(:field_commit_logs_encoding), :required => true)) | |
237 end | |
238 | |
239 def filesystem_field_tags(form, repository) | |
240 content_tag('p', form.text_field( | |
241 :url, :label => l(:field_root_directory), | |
242 :size => 60, :required => true, | |
243 :disabled => !repository.safe_attribute?('url'))) + | |
244 content_tag('p', form.select( | |
245 :path_encoding, [nil] + Setting::ENCODINGS, | |
246 :label => l(:field_scm_path_encoding) | |
247 ) + | |
248 '<br />'.html_safe + l(:text_scm_path_encoding_note)) | |
249 end | |
250 | |
251 def index_commits(commits, heads) | |
252 return nil if commits.nil? or commits.first.parents.nil? | |
253 refs_map = {} | |
254 heads.each do |head| | |
255 refs_map[head.scmid] ||= [] | |
256 refs_map[head.scmid] << head | |
257 end | |
258 commits_by_scmid = {} | |
259 commits.reverse.each_with_index do |commit, commit_index| | |
260 commits_by_scmid[commit.scmid] = { | |
261 :parent_scmids => commit.parents.collect { |parent| parent.scmid }, | |
262 :rdmid => commit_index, | |
263 :refs => refs_map.include?(commit.scmid) ? refs_map[commit.scmid].join(" ") : nil, | |
264 :scmid => commit.scmid, | |
265 :href => block_given? ? yield(commit.scmid) : commit.scmid | |
266 } | |
267 end | |
268 heads.sort! { |head1, head2| head1.to_s <=> head2.to_s } | |
269 space = nil | |
270 heads.each do |head| | |
271 if commits_by_scmid.include? head.scmid | |
272 space = index_head((space || -1) + 1, head, commits_by_scmid) | |
273 end | |
274 end | |
275 # when no head matched anything use first commit | |
276 space ||= index_head(0, commits.first, commits_by_scmid) | |
277 return commits_by_scmid, space | |
278 end | |
279 | |
280 def index_head(space, commit, commits_by_scmid) | |
281 stack = [[space, commits_by_scmid[commit.scmid]]] | |
282 max_space = space | |
283 until stack.empty? | |
284 space, commit = stack.pop | |
285 commit[:space] = space if commit[:space].nil? | |
286 space -= 1 | |
287 commit[:parent_scmids].each_with_index do |parent_scmid, parent_index| | |
288 parent_commit = commits_by_scmid[parent_scmid] | |
289 if parent_commit and parent_commit[:space].nil? | |
290 stack.unshift [space += 1, parent_commit] | |
291 end | |
292 end | |
293 max_space = space if max_space < space | |
294 end | |
295 max_space | |
296 end | |
297 end |