2014-08-26 16:32:41 -04:00
|
|
|
module Gitlab
|
|
|
|
class ProjectSearchResults < SearchResults
|
|
|
|
attr_reader :project, :repository_ref
|
|
|
|
|
2018-01-31 09:59:59 -05:00
|
|
|
def initialize(current_user, project, query, repository_ref = nil, per_page: 20)
|
2016-03-17 16:48:19 -04:00
|
|
|
@current_user = current_user
|
2016-03-01 12:04:37 -05:00
|
|
|
@project = project
|
2016-11-10 12:27:09 -05:00
|
|
|
@repository_ref = repository_ref.presence || project.default_branch
|
2015-10-14 19:14:24 -04:00
|
|
|
@query = query
|
2018-01-31 09:59:59 -05:00
|
|
|
@per_page = per_page
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2018-02-06 11:53:42 -05:00
|
|
|
def objects(scope, page = nil)
|
2014-08-26 16:32:41 -04:00
|
|
|
case scope
|
|
|
|
when 'notes'
|
|
|
|
notes.page(page).per(per_page)
|
|
|
|
when 'blobs'
|
|
|
|
Kaminari.paginate_array(blobs).page(page).per(per_page)
|
2014-09-05 06:33:05 -04:00
|
|
|
when 'wiki_blobs'
|
|
|
|
Kaminari.paginate_array(wiki_blobs).page(page).per(per_page)
|
2015-06-14 18:04:20 -04:00
|
|
|
when 'commits'
|
|
|
|
Kaminari.paginate_array(commits).page(page).per(per_page)
|
2014-08-26 16:32:41 -04:00
|
|
|
else
|
2018-02-06 11:53:42 -05:00
|
|
|
super(scope, page, false)
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def blobs_count
|
|
|
|
@blobs_count ||= blobs.count
|
|
|
|
end
|
|
|
|
|
2018-03-05 08:25:56 -05:00
|
|
|
def limited_notes_count
|
|
|
|
return @limited_notes_count if defined?(@limited_notes_count)
|
|
|
|
|
|
|
|
types = %w(issue merge_request commit snippet)
|
|
|
|
@limited_notes_count = 0
|
|
|
|
|
|
|
|
types.each do |type|
|
|
|
|
@limited_notes_count += notes_finder(type).limit(count_limit).count
|
|
|
|
break if @limited_notes_count >= count_limit
|
|
|
|
end
|
|
|
|
|
|
|
|
@limited_notes_count
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2014-09-05 06:33:05 -04:00
|
|
|
def wiki_blobs_count
|
|
|
|
@wiki_blobs_count ||= wiki_blobs.count
|
|
|
|
end
|
|
|
|
|
2015-06-14 18:04:20 -04:00
|
|
|
def commits_count
|
|
|
|
@commits_count ||= commits.count
|
|
|
|
end
|
|
|
|
|
2018-02-13 07:41:35 -05:00
|
|
|
def self.parse_search_result(result, project = nil)
|
2016-11-10 12:27:09 -05:00
|
|
|
ref = nil
|
|
|
|
filename = nil
|
|
|
|
basename = nil
|
2018-01-15 09:49:27 -05:00
|
|
|
data = ""
|
2016-11-10 12:27:09 -05:00
|
|
|
startline = 0
|
|
|
|
|
2018-03-15 12:11:20 -04:00
|
|
|
result.each_line.each_with_index do |line, index|
|
2018-01-15 09:49:27 -05:00
|
|
|
prefix ||= line.match(/^(?<ref>[^:]*):(?<filename>.*)\x00(?<startline>\d+)\x00/)&.tap do |matches|
|
2017-11-30 04:57:58 -05:00
|
|
|
ref = matches[:ref]
|
|
|
|
filename = matches[:filename]
|
|
|
|
startline = matches[:startline]
|
2016-11-10 12:27:09 -05:00
|
|
|
startline = startline.to_i - index
|
|
|
|
extname = Regexp.escape(File.extname(filename))
|
|
|
|
basename = filename.sub(/#{extname}$/, '')
|
|
|
|
end
|
|
|
|
|
2018-01-15 09:49:27 -05:00
|
|
|
data << line.sub(prefix.to_s, '')
|
2016-11-10 12:27:09 -05:00
|
|
|
end
|
|
|
|
|
2017-04-03 13:31:52 -04:00
|
|
|
FoundBlob.new(
|
2016-11-10 12:27:09 -05:00
|
|
|
filename: filename,
|
|
|
|
basename: basename,
|
|
|
|
ref: ref,
|
|
|
|
startline: startline,
|
2018-02-13 07:41:35 -05:00
|
|
|
data: data,
|
|
|
|
project_id: project ? project.id : nil
|
2016-11-10 12:27:09 -05:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2017-01-10 23:20:32 -05:00
|
|
|
def single_commit_result?
|
2018-03-05 08:25:56 -05:00
|
|
|
return false if commits_count != 1
|
2017-01-10 23:20:32 -05:00
|
|
|
|
2018-03-05 08:25:56 -05:00
|
|
|
counts = %i(limited_milestones_count limited_notes_count
|
|
|
|
limited_merge_requests_count limited_issues_count
|
|
|
|
blobs_count wiki_blobs_count)
|
|
|
|
counts.all? { |count_method| public_send(count_method).zero? } # rubocop:disable GitlabSecurity/PublicSend
|
2017-01-10 23:20:32 -05:00
|
|
|
end
|
|
|
|
|
2014-08-26 16:32:41 -04:00
|
|
|
private
|
|
|
|
|
|
|
|
def blobs
|
2017-04-24 11:09:29 -04:00
|
|
|
return [] unless Ability.allowed?(@current_user, :download_code, @project)
|
|
|
|
|
2017-05-12 03:16:33 -04:00
|
|
|
@blobs ||= Gitlab::FileFinder.new(project, repository_ref).find(query)
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2014-09-05 06:33:05 -04:00
|
|
|
def wiki_blobs
|
2017-04-24 11:09:29 -04:00
|
|
|
return [] unless Ability.allowed?(@current_user, :read_wiki, @project)
|
|
|
|
|
2016-11-08 07:21:19 -05:00
|
|
|
@wiki_blobs ||= begin
|
|
|
|
if project.wiki_enabled? && query.present?
|
|
|
|
project_wiki = ProjectWiki.new(project)
|
2014-09-09 10:56:33 -04:00
|
|
|
|
2016-11-08 07:21:19 -05:00
|
|
|
unless project_wiki.empty?
|
|
|
|
project_wiki.search_files(query)
|
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
2014-09-09 10:56:33 -04:00
|
|
|
else
|
|
|
|
[]
|
|
|
|
end
|
2014-09-05 06:33:05 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-08-26 16:32:41 -04:00
|
|
|
def notes
|
2018-03-05 08:25:56 -05:00
|
|
|
@notes ||= notes_finder(nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
def notes_finder(type)
|
|
|
|
NotesFinder.new(project, @current_user, search: query, target_type: type).execute.user.order('updated_at DESC')
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
|
2015-06-14 18:04:20 -04:00
|
|
|
def commits
|
2016-12-08 09:54:45 -05:00
|
|
|
@commits ||= find_commits(query)
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_commits(query)
|
|
|
|
return [] unless Ability.allowed?(@current_user, :download_code, @project)
|
|
|
|
|
|
|
|
commits = find_commits_by_message(query)
|
|
|
|
commit_by_sha = find_commit_by_sha(query)
|
2017-01-10 23:20:32 -05:00
|
|
|
commits |= [commit_by_sha] if commit_by_sha
|
2016-12-08 09:54:45 -05:00
|
|
|
commits
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_commits_by_message(query)
|
|
|
|
project.repository.find_commits_by_message(query)
|
|
|
|
end
|
|
|
|
|
|
|
|
def find_commit_by_sha(query)
|
|
|
|
key = query.strip
|
|
|
|
project.repository.commit(key) if Commit.valid_hash?(key)
|
2015-06-14 18:04:20 -04:00
|
|
|
end
|
2016-03-03 09:10:14 -05:00
|
|
|
|
|
|
|
def project_ids_relation
|
|
|
|
project
|
|
|
|
end
|
2014-08-26 16:32:41 -04:00
|
|
|
end
|
|
|
|
end
|