From fa2915ec2deaf9aa73ae18a60836a831376da943 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 24 Aug 2017 14:46:08 +0100 Subject: Fix searching for files by path --- .../unreleased/36939-fix-find-blobs-by-path.yml | 5 +++ lib/gitlab/file_finder.rb | 43 ++++++++++++++++------ spec/lib/gitlab/file_finder_spec.rb | 14 +++++-- 3 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 changelogs/unreleased/36939-fix-find-blobs-by-path.yml 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 -- cgit v1.2.1