Merge branch '18590-banzai-filter-relativelinkfilter-is-slow' into 'master'
Optimize Banzai::Filter::RelativeLinkFilter See merge request !4813
This commit is contained in:
commit
15a87f3129
|
@ -9,6 +9,7 @@ v 8.9.0 (unreleased)
|
|||
- Bulk assign/unassign labels to issues.
|
||||
- Ability to prioritize labels !4009 / !3205 (Thijs Wouters)
|
||||
- Show Star and Fork buttons on mobile.
|
||||
- Performance improvements on RelativeLinkFilter
|
||||
- Fix endless redirections when accessing user OAuth applications when they are disabled
|
||||
- Allow enabling wiki page events from Webhook management UI
|
||||
- Bump rouge to 1.11.0
|
||||
|
|
|
@ -271,6 +271,32 @@ class Commit
|
|||
merged_merge_request ? 'merge request' : 'commit'
|
||||
end
|
||||
|
||||
# Get the URI type of the given path
|
||||
#
|
||||
# Used to build URLs to files in the repository in GFM.
|
||||
#
|
||||
# path - String path to check
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# uri_type('doc/README.md') # => :blob
|
||||
# uri_type('doc/logo.png') # => :raw
|
||||
# uri_type('doc/api') # => :tree
|
||||
# uri_type('not/found') # => :nil
|
||||
#
|
||||
# Returns a symbol
|
||||
def uri_type(path)
|
||||
entry = @raw.tree.path(path)
|
||||
if entry[:type] == :blob
|
||||
blob = Gitlab::Git::Blob.new(name: entry[:name])
|
||||
blob.image? ? :raw : :blob
|
||||
else
|
||||
entry[:type]
|
||||
end
|
||||
rescue Rugged::TreeError
|
||||
nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def repo_changes
|
||||
|
|
|
@ -14,6 +14,8 @@ module Banzai
|
|||
def call
|
||||
return doc unless linkable_files?
|
||||
|
||||
@uri_types = {}
|
||||
|
||||
doc.search('a:not(.gfm)').each do |el|
|
||||
process_link_attr el.attribute('href')
|
||||
end
|
||||
|
@ -48,7 +50,7 @@ module Banzai
|
|||
uri.path = [
|
||||
relative_url_root,
|
||||
context[:project].path_with_namespace,
|
||||
path_type(file_path),
|
||||
uri_type(file_path),
|
||||
ref || context[:project].default_branch, # if no ref exists, point to the default branch
|
||||
file_path
|
||||
].compact.join('/').squeeze('/').chomp('/')
|
||||
|
@ -87,7 +89,7 @@ module Banzai
|
|||
return path unless request_path
|
||||
|
||||
parts = request_path.split('/')
|
||||
parts.pop if path_type(request_path) != 'tree'
|
||||
parts.pop if uri_type(request_path) != :tree
|
||||
|
||||
while path.start_with?('../')
|
||||
parts.pop
|
||||
|
@ -98,45 +100,20 @@ module Banzai
|
|||
end
|
||||
|
||||
def file_exists?(path)
|
||||
return false if path.nil?
|
||||
repository.blob_at(current_sha, path).present? ||
|
||||
repository.tree(current_sha, path).entries.any?
|
||||
path.present? && !!uri_type(path)
|
||||
end
|
||||
|
||||
# Get the type of the given path
|
||||
#
|
||||
# path - String path to check
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# path_type('doc/README.md') # => 'blob'
|
||||
# path_type('doc/logo.png') # => 'raw'
|
||||
# path_type('doc/api') # => 'tree'
|
||||
#
|
||||
# Returns a String
|
||||
def path_type(path)
|
||||
unescaped_path = Addressable::URI.unescape(path)
|
||||
def uri_type(path)
|
||||
@uri_types[path] ||= begin
|
||||
unescaped_path = Addressable::URI.unescape(path)
|
||||
|
||||
if tree?(unescaped_path)
|
||||
'tree'
|
||||
elsif image?(unescaped_path)
|
||||
'raw'
|
||||
else
|
||||
'blob'
|
||||
current_commit.uri_type(unescaped_path)
|
||||
end
|
||||
end
|
||||
|
||||
def tree?(path)
|
||||
repository.tree(current_sha, path).entries.any?
|
||||
end
|
||||
|
||||
def image?(path)
|
||||
repository.blob_at(current_sha, path).try(:image?)
|
||||
end
|
||||
|
||||
def current_sha
|
||||
context[:commit].try(:id) ||
|
||||
ref ? repository.commit(ref).try(:sha) : repository.head_commit.sha
|
||||
def current_commit
|
||||
@current_commit ||= context[:commit] ||
|
||||
ref ? repository.commit(ref) : repository.head_commit
|
||||
end
|
||||
|
||||
def relative_url_root
|
||||
|
@ -148,7 +125,7 @@ module Banzai
|
|||
end
|
||||
|
||||
def repository
|
||||
context[:project].try(:repository)
|
||||
@repository ||= context[:project].try(:repository)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -132,11 +132,8 @@ describe Banzai::Filter::RelativeLinkFilter, lib: true do
|
|||
path = 'files/images/한글.png'
|
||||
escaped = Addressable::URI.escape(path)
|
||||
|
||||
# Stub these methods so the file doesn't actually need to be in the repo
|
||||
allow_any_instance_of(described_class).
|
||||
to receive(:file_exists?).and_return(true)
|
||||
allow_any_instance_of(described_class).
|
||||
to receive(:image?).with(path).and_return(true)
|
||||
# Stub this method so the file doesn't actually need to be in the repo
|
||||
allow_any_instance_of(described_class).to receive(:uri_type).and_return(:raw)
|
||||
|
||||
doc = filter(image(escaped))
|
||||
expect(doc.at_css('img')['src']).to match '/raw/'
|
||||
|
|
|
@ -207,4 +207,16 @@ eos
|
|||
expect(commit.participants).to include(note1.author, note2.author)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#uri_type' do
|
||||
it 'returns the URI type at the given path' do
|
||||
expect(commit.uri_type('files/html')).to be(:tree)
|
||||
expect(commit.uri_type('files/images/logo-black.png')).to be(:raw)
|
||||
expect(commit.uri_type('files/js/application.js')).to be(:blob)
|
||||
end
|
||||
|
||||
it "returns nil if the path doesn't exists" do
|
||||
expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue