summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Thomas <nick@gitlab.com>2017-08-24 14:46:08 +0100
committerNick Thomas <nick@gitlab.com>2017-08-25 10:36:32 +0100
commitfa2915ec2deaf9aa73ae18a60836a831376da943 (patch)
tree52ca1260718fe6639008f4365180342add4ec64f
parenteae604e6de0136f2cc1c06b48fb1503408059ce8 (diff)
downloadgitlab-ce-fa2915ec2deaf9aa73ae18a60836a831376da943.tar.gz
Fix searching for files by path
-rw-r--r--changelogs/unreleased/36939-fix-find-blobs-by-path.yml5
-rw-r--r--lib/gitlab/file_finder.rb43
-rw-r--r--spec/lib/gitlab/file_finder_spec.rb14
3 files changed, 48 insertions, 14 deletions
diff --git a/changelogs/unreleased/36939-fix-find-blobs-by-path.yml b/changelogs/unreleased/36939-fix-find-blobs-by-path.yml
new file mode 100644
index 00000000000..b48b10049ed
--- /dev/null
+++ b/changelogs/unreleased/36939-fix-find-blobs-by-path.yml
@@ -0,0 +1,5 @@
+---
+title: Fix searching for files by path
+merge_request: 13798
+author:
+type: fixed
diff --git a/lib/gitlab/file_finder.rb b/lib/gitlab/file_finder.rb
index 093d9ed8092..10ffc345bd5 100644
--- a/lib/gitlab/file_finder.rb
+++ b/lib/gitlab/file_finder.rb
@@ -6,27 +6,48 @@ module Gitlab
attr_reader :project, :ref
+ delegate :repository, to: :project
+
def initialize(project, ref)
@project = project
@ref = ref
end
def find(query)
- blobs = project.repository.search_files_by_content(query, ref).first(BATCH_SIZE)
- found_file_names = Set.new
+ by_content = find_by_content(query)
- results = blobs.map do |blob|
- blob = Gitlab::ProjectSearchResults.parse_search_result(blob)
- found_file_names << blob.filename
+ already_found = Set.new(by_content.map(&:filename))
+ by_filename = find_by_filename(query, except: already_found)
- [blob.filename, blob]
- end
+ (by_content + by_filename)
+ .sort_by(&:filename)
+ .map { |blob| [blob.filename, blob] }
+ end
- project.repository.search_files_by_name(query, ref).first(BATCH_SIZE).each do |filename|
- results << [filename, OpenStruct.new(ref: ref)] unless found_file_names.include?(filename)
- end
+ private
- results.sort_by(&:first)
+ def find_by_content(query)
+ results = repository.search_files_by_content(query, ref).first(BATCH_SIZE)
+ results.map { |result| Gitlab::ProjectSearchResults.parse_search_result(result) }
+ end
+
+ def find_by_filename(query, except: [])
+ filenames = repository.search_files_by_name(query, ref).first(BATCH_SIZE)
+ filenames.delete_if { |filename| except.include?(filename) } unless except.empty?
+
+ blob_refs = filenames.map { |filename| [ref, filename] }
+ blobs = Gitlab::Git::Blob.batch(repository, blob_refs, blob_size_limit: 1024)
+
+ blobs.map do |blob|
+ Gitlab::SearchResults::FoundBlob.new(
+ id: blob.id,
+ filename: blob.path,
+ basename: File.basename(blob.path),
+ ref: ref,
+ startline: 1,
+ data: blob.data
+ )
+ end
end
end
end
diff --git a/spec/lib/gitlab/file_finder_spec.rb b/spec/lib/gitlab/file_finder_spec.rb
index 3fb6315a39a..07cb10e563e 100644
--- a/spec/lib/gitlab/file_finder_spec.rb
+++ b/spec/lib/gitlab/file_finder_spec.rb
@@ -7,15 +7,23 @@ describe Gitlab::FileFinder do
it 'finds by name' do
results = finder.find('files')
- expect(results.map(&:first)).to include('files/images/wm.svg')
+
+ filename, blob = results.find { |_, blob| blob.filename == 'files/images/wm.svg' }
+ expect(filename).to eq('files/images/wm.svg')
+ expect(blob).to be_a(Gitlab::SearchResults::FoundBlob)
+ expect(blob.ref).to eq(finder.ref)
+ expect(blob.data).not_to be_empty
end
it 'finds by content' do
results = finder.find('files')
- blob = results.select { |result| result.first == "CHANGELOG" }.flatten.last
+ filename, blob = results.find { |_, blob| blob.filename == 'CHANGELOG' }
- expect(blob.filename).to eq("CHANGELOG")
+ expect(filename).to eq('CHANGELOG')
+ expect(blob).to be_a(Gitlab::SearchResults::FoundBlob)
+ expect(blob.ref).to eq(finder.ref)
+ expect(blob.data).not_to be_empty
end
end
end