gitlab_reviewable 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +37 -0
- data/app/controllers/gitlab_reviewable/reviews_controller.rb +58 -0
- data/app/helpers/gitlab_reviewable/reviews_helper.rb +377 -0
- data/app/views/gitlab_reviewable/reviews/diffs.html.haml +53 -0
- data/app/views/gitlab_reviewable/reviews/discussion.html.haml +55 -0
- data/app/views/layouts/review.haml +34 -0
- data/config/routes.rb +5 -0
- data/lib/gitlab_reviewable.rb +4 -0
- data/lib/gitlab_reviewable/engine.rb +5 -0
- data/lib/gitlab_reviewable/version.rb +3 -0
- data/lib/tasks/gitlab_reviewable_tasks.rake +4 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +423 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/gitlab_reviewable_test.rb +7 -0
- data/test/integration/navigation_test.rb +8 -0
- data/test/test_helper.rb +21 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e106229e4eeb661a205c46cda1f073d0dad6ed40
|
4
|
+
data.tar.gz: eaf7dec42bf9a8e4422b81e40942983570c2c20b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2ed83457388686dd79b7075b4d8188462cee050032bfd6da476856b24df4670c00a7bcd13f21d162955e2f389f76b0d450084bd3790a92f2f814d515c00813a1
|
7
|
+
data.tar.gz: 5c380c55e79e638b3e493858a2e4de320c1047376b04bf48e664a34be9366000f7e716f909333a8d38e44c4ffd26ecba06294d7fe2539f768382de8d778c6f5d
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2017 lenghan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'GitlabReviewable'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
Bundler::GemHelper.install_tasks
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module GitlabReviewable
|
2
|
+
class ReviewsController < ApplicationController
|
3
|
+
include DiffHelper
|
4
|
+
|
5
|
+
skip_before_action :authenticate_user!
|
6
|
+
before_action :merge_request
|
7
|
+
before_action :define_show_vars
|
8
|
+
layout 'review'
|
9
|
+
|
10
|
+
def diffs
|
11
|
+
puts 111111
|
12
|
+
@note_counts = Note.where(commit_id: @merge_request.commits.map(&:id)).
|
13
|
+
group(:commit_id).count
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.html
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def discussion
|
21
|
+
@note_counts = Note.where(commit_id: @merge_request.commits.map(&:id)).
|
22
|
+
group(:commit_id).count
|
23
|
+
|
24
|
+
respond_to do |format|
|
25
|
+
format.html
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def merge_request
|
32
|
+
@project = Project.find_by!(id: params[:project_id])
|
33
|
+
@merge_request ||= @project.merge_requests.find_by!(iid: params[:merge_request_id])
|
34
|
+
end
|
35
|
+
|
36
|
+
def define_show_vars
|
37
|
+
# Build a note object for comment form
|
38
|
+
@note = @project.notes.new(noteable: @merge_request)
|
39
|
+
@notes = @merge_request.mr_and_commit_notes.nonawards.inc_author.fresh
|
40
|
+
@discussions = @notes.discussions
|
41
|
+
@noteable = @merge_request
|
42
|
+
|
43
|
+
# Get commits from repository
|
44
|
+
# or from cache if already merged
|
45
|
+
@commits = @merge_request.commits
|
46
|
+
|
47
|
+
@merge_request_diff = @merge_request.merge_request_diff
|
48
|
+
|
49
|
+
@ci_commit = @merge_request.ci_commit
|
50
|
+
@statuses = @ci_commit.statuses if @ci_commit
|
51
|
+
|
52
|
+
if @merge_request.locked_long_ago?
|
53
|
+
@merge_request.unlock_mr
|
54
|
+
@merge_request.close
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,377 @@
|
|
1
|
+
module GitlabReviewable
|
2
|
+
module ReviewsHelper
|
3
|
+
def method_missing method, *args, &block
|
4
|
+
if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
|
5
|
+
if main_app.respond_to?(method)
|
6
|
+
main_app.send(method, *args)
|
7
|
+
else
|
8
|
+
super
|
9
|
+
end
|
10
|
+
else
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def respond_to?(method)
|
16
|
+
if method.to_s.end_with?('_path') or method.to_s.end_with?('_url')
|
17
|
+
if main_app.respond_to?(method)
|
18
|
+
true
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
else
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_from_project_team_message(project, member)
|
28
|
+
if member.user
|
29
|
+
"You are going to remove #{member.user.name} from #{project.name} project team. Are you sure?"
|
30
|
+
else
|
31
|
+
"You are going to revoke the invitation for #{member.invite_email} to join #{project.name} project team. Are you sure?"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def link_to_project(project)
|
36
|
+
link_to [project.namespace.becomes(Namespace), project], title: h(project.name) do
|
37
|
+
title = content_tag(:span, project.name, class: 'project-name')
|
38
|
+
|
39
|
+
if project.namespace
|
40
|
+
namespace = content_tag(:span, "#{project.namespace.human_name} / ", class: 'namespace-name')
|
41
|
+
title = namespace + title
|
42
|
+
end
|
43
|
+
|
44
|
+
title
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def link_to_member_avatar(author, opts = {})
|
49
|
+
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
|
50
|
+
opts = default_opts.merge(opts)
|
51
|
+
image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
|
52
|
+
end
|
53
|
+
|
54
|
+
def link_to_member(project, author, opts = {}, &block)
|
55
|
+
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
|
56
|
+
opts = default_opts.merge(opts)
|
57
|
+
|
58
|
+
return "(deleted)" unless author
|
59
|
+
|
60
|
+
author_html = ""
|
61
|
+
|
62
|
+
# Build avatar image tag
|
63
|
+
author_html << image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
|
64
|
+
|
65
|
+
# Build name span tag
|
66
|
+
if opts[:by_username]
|
67
|
+
author_html << content_tag(:span, sanitize("@#{author.username}"), class: opts[:author_class]) if opts[:name]
|
68
|
+
else
|
69
|
+
author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name]
|
70
|
+
end
|
71
|
+
|
72
|
+
author_html << capture(&block) if block
|
73
|
+
|
74
|
+
author_html = author_html.html_safe
|
75
|
+
|
76
|
+
if opts[:name]
|
77
|
+
link_to(author_html, user_path(author), class: "author_link #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe
|
78
|
+
else
|
79
|
+
title = opts[:title].sub(":name", sanitize(author.name))
|
80
|
+
link_to(author_html, user_path(author), class: "author_link has-tooltip", title: title, data: { container: 'body' } ).html_safe
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def project_title(project, name = nil, url = nil)
|
85
|
+
namespace_link =
|
86
|
+
if project.group
|
87
|
+
link_to(simple_sanitize(project.group.name), group_path(project.group))
|
88
|
+
else
|
89
|
+
owner = project.namespace.owner
|
90
|
+
link_to(simple_sanitize(owner.name), user_path(owner))
|
91
|
+
end
|
92
|
+
|
93
|
+
project_link = link_to simple_sanitize(project.name), '#', { class: "project-item-select-holder" }
|
94
|
+
|
95
|
+
if current_user
|
96
|
+
project_link << icon("chevron-down", class: "dropdown-toggle-caret js-projects-dropdown-toggle", data: { target: ".js-dropdown-menu-projects", toggle: "dropdown" })
|
97
|
+
end
|
98
|
+
|
99
|
+
full_title = "#{namespace_link} / #{project_link}".html_safe
|
100
|
+
full_title << ' · '.html_safe << link_to(simple_sanitize(name), url) if name
|
101
|
+
|
102
|
+
full_title
|
103
|
+
end
|
104
|
+
|
105
|
+
def remove_project_message(project)
|
106
|
+
"You are going to remove #{project.name_with_namespace}.\n Removed project CANNOT be restored!\n Are you ABSOLUTELY sure?"
|
107
|
+
end
|
108
|
+
|
109
|
+
def transfer_project_message(project)
|
110
|
+
"You are going to transfer #{project.name_with_namespace} to another owner. Are you ABSOLUTELY sure?"
|
111
|
+
end
|
112
|
+
|
113
|
+
def remove_fork_project_message(project)
|
114
|
+
"You are going to remove the fork relationship to source project #{@project.forked_from_project.name_with_namespace}. Are you ABSOLUTELY sure?"
|
115
|
+
end
|
116
|
+
|
117
|
+
def project_nav_tabs
|
118
|
+
@nav_tabs ||= get_project_nav_tabs(@project, current_user)
|
119
|
+
end
|
120
|
+
|
121
|
+
def project_nav_tab?(name)
|
122
|
+
project_nav_tabs.include? name
|
123
|
+
end
|
124
|
+
|
125
|
+
def project_for_deploy_key(deploy_key)
|
126
|
+
if deploy_key.projects.include?(@project)
|
127
|
+
@project
|
128
|
+
else
|
129
|
+
deploy_key.projects.find { |project| can?(current_user, :read_project, project) }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def can_change_visibility_level?(project, current_user)
|
134
|
+
return false unless can?(current_user, :change_visibility_level, project)
|
135
|
+
|
136
|
+
if project.forked?
|
137
|
+
project.forked_from_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE
|
138
|
+
else
|
139
|
+
true
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def user_max_access_in_project(user_id, project)
|
144
|
+
level = project.team.max_member_access(user_id)
|
145
|
+
|
146
|
+
if level
|
147
|
+
Gitlab::Access.options_with_owner.key(level)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def license_short_name(project)
|
152
|
+
return 'LICENSE' if project.repository.license_key.nil?
|
153
|
+
|
154
|
+
license = Licensee::License.new(project.repository.license_key)
|
155
|
+
|
156
|
+
license.nickname || license.name
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def get_project_nav_tabs(project, current_user)
|
162
|
+
nav_tabs = [:home]
|
163
|
+
|
164
|
+
if !project.empty_repo? && can?(current_user, :download_code, project)
|
165
|
+
nav_tabs << [:files, :commits, :network, :graphs, :forks]
|
166
|
+
end
|
167
|
+
|
168
|
+
if project.repo_exists? && can?(current_user, :read_merge_request, project)
|
169
|
+
nav_tabs << :merge_requests
|
170
|
+
end
|
171
|
+
|
172
|
+
if can?(current_user, :read_pipeline, project)
|
173
|
+
nav_tabs << :pipelines
|
174
|
+
end
|
175
|
+
|
176
|
+
if can?(current_user, :read_build, project)
|
177
|
+
nav_tabs << :builds
|
178
|
+
end
|
179
|
+
|
180
|
+
if Gitlab.config.registry.enabled && can?(current_user, :read_container_image, project)
|
181
|
+
nav_tabs << :container_registry
|
182
|
+
end
|
183
|
+
|
184
|
+
if can?(current_user, :admin_project, project)
|
185
|
+
nav_tabs << :settings
|
186
|
+
end
|
187
|
+
|
188
|
+
if can?(current_user, :read_project_member, project)
|
189
|
+
nav_tabs << :team
|
190
|
+
end
|
191
|
+
|
192
|
+
if can?(current_user, :read_issue, project)
|
193
|
+
nav_tabs << :issues
|
194
|
+
end
|
195
|
+
|
196
|
+
if can?(current_user, :read_wiki, project)
|
197
|
+
nav_tabs << :wiki
|
198
|
+
end
|
199
|
+
|
200
|
+
if can?(current_user, :read_project_snippet, project)
|
201
|
+
nav_tabs << :snippets
|
202
|
+
end
|
203
|
+
|
204
|
+
if can?(current_user, :read_label, project)
|
205
|
+
nav_tabs << :labels
|
206
|
+
end
|
207
|
+
|
208
|
+
if can?(current_user, :read_milestone, project)
|
209
|
+
nav_tabs << :milestones
|
210
|
+
end
|
211
|
+
|
212
|
+
nav_tabs.flatten
|
213
|
+
end
|
214
|
+
|
215
|
+
def git_user_name
|
216
|
+
if current_user
|
217
|
+
current_user.name
|
218
|
+
else
|
219
|
+
"Your name"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def git_user_email
|
224
|
+
if current_user
|
225
|
+
current_user.email
|
226
|
+
else
|
227
|
+
"your@email.com"
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def repository_size(project = @project)
|
232
|
+
size_in_bytes = project.repository_size * 1.megabyte
|
233
|
+
number_to_human_size(size_in_bytes, delimiter: ',', precision: 2)
|
234
|
+
end
|
235
|
+
|
236
|
+
def default_url_to_repo(project = @project)
|
237
|
+
case default_clone_protocol
|
238
|
+
when 'ssh'
|
239
|
+
project.ssh_url_to_repo
|
240
|
+
else
|
241
|
+
project.http_url_to_repo
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def default_clone_protocol
|
246
|
+
if !current_user || current_user.require_ssh_key?
|
247
|
+
gitlab_config.protocol
|
248
|
+
else
|
249
|
+
"ssh"
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def project_last_activity(project)
|
254
|
+
if project.last_activity_at
|
255
|
+
time_ago_with_tooltip(project.last_activity_at, placement: 'bottom', html_class: 'last_activity_time_ago')
|
256
|
+
else
|
257
|
+
"Never"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def add_special_file_path(project, file_name:, commit_message: nil)
|
262
|
+
namespace_project_new_blob_path(
|
263
|
+
project.namespace,
|
264
|
+
project,
|
265
|
+
project.default_branch || 'master',
|
266
|
+
file_name: file_name,
|
267
|
+
commit_message: commit_message || "Add #{file_name.downcase}"
|
268
|
+
)
|
269
|
+
end
|
270
|
+
|
271
|
+
def contribution_guide_path(project)
|
272
|
+
if project && contribution_guide = project.repository.contribution_guide
|
273
|
+
namespace_project_blob_path(
|
274
|
+
project.namespace,
|
275
|
+
project,
|
276
|
+
tree_join(project.default_branch,
|
277
|
+
contribution_guide.name)
|
278
|
+
)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def readme_path(project)
|
283
|
+
filename_path(project, :readme)
|
284
|
+
end
|
285
|
+
|
286
|
+
def changelog_path(project)
|
287
|
+
filename_path(project, :changelog)
|
288
|
+
end
|
289
|
+
|
290
|
+
def license_path(project)
|
291
|
+
filename_path(project, :license_blob)
|
292
|
+
end
|
293
|
+
|
294
|
+
def version_path(project)
|
295
|
+
filename_path(project, :version)
|
296
|
+
end
|
297
|
+
|
298
|
+
def project_wiki_path_with_version(proj, page, version, is_newest)
|
299
|
+
url_params = is_newest ? {} : { version_id: version }
|
300
|
+
namespace_project_wiki_path(proj.namespace, proj, page, url_params)
|
301
|
+
end
|
302
|
+
|
303
|
+
def project_status_css_class(status)
|
304
|
+
case status
|
305
|
+
when "started"
|
306
|
+
"active"
|
307
|
+
when "failed"
|
308
|
+
"danger"
|
309
|
+
when "finished"
|
310
|
+
"success"
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def leave_project_message(project)
|
315
|
+
"Are you sure you want to leave \"#{project.name}\" project?"
|
316
|
+
end
|
317
|
+
|
318
|
+
def new_readme_path
|
319
|
+
ref = @repository.root_ref if @repository
|
320
|
+
ref ||= 'master'
|
321
|
+
|
322
|
+
namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'README.md')
|
323
|
+
end
|
324
|
+
|
325
|
+
def new_license_path
|
326
|
+
ref = @repository.root_ref if @repository
|
327
|
+
ref ||= 'master'
|
328
|
+
|
329
|
+
namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'LICENSE')
|
330
|
+
end
|
331
|
+
|
332
|
+
def last_push_event
|
333
|
+
if current_user
|
334
|
+
current_user.recent_push(@project.id)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def readme_cache_key
|
339
|
+
sha = @project.commit.try(:sha) || 'nil'
|
340
|
+
[@project.path_with_namespace, sha, "readme"].join('-')
|
341
|
+
end
|
342
|
+
|
343
|
+
def round_commit_count(project)
|
344
|
+
count = project.commit_count
|
345
|
+
|
346
|
+
if count > 10000
|
347
|
+
'10000+'
|
348
|
+
elsif count > 5000
|
349
|
+
'5000+'
|
350
|
+
elsif count > 1000
|
351
|
+
'1000+'
|
352
|
+
else
|
353
|
+
count
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def current_ref
|
358
|
+
@ref || @repository.try(:root_ref)
|
359
|
+
end
|
360
|
+
|
361
|
+
def filename_path(project, filename)
|
362
|
+
if project && blob = project.repository.send(filename)
|
363
|
+
namespace_project_blob_path(
|
364
|
+
project.namespace,
|
365
|
+
project,
|
366
|
+
tree_join(project.default_branch, blob.name)
|
367
|
+
)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def sanitize_repo_path(message)
|
372
|
+
return '' unless message.present?
|
373
|
+
|
374
|
+
message.strip.gsub(Gitlab.config.gitlab_shell.repos_path.chomp('/'), "[REPOS PATH]")
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|