diff options
author | Nick Thomas <nick@gitlab.com> | 2018-10-12 16:42:35 +0300 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2018-10-17 18:24:36 +0300 |
commit | 0669127a328af171850afb01deef2a07eb89a6a6 (patch) | |
tree | 8a25b2e738eb131f89b21ce1cb93442ae89b6299 /app | |
parent | e347170cc59dfa1e48de451f7c48ccb65d3e581a (diff) |
Use cached readme blobs where appropriate
GitLab keeps a cache of the rendered HTML for a repository's README as
stored in the HEAD branch. However, it was not used in all
circumstances. In particular, the new blob viewer framework bypassed
this cache entirely.
This MR ensures a ::ReadmeBlob is returned instead of a ::Blob when
asking a repository for an individual blob, if the commit and path
match the readme for HEAD. This makes the cached HTML available to
consumers, including the blob viewer.
The ReadmeBlob is a simple delegator to the Blob, so should be
compatible in all cases. Adding the rendered_markdown method is the
only additional behaviour it contains.
Diffstat (limited to 'app')
-rw-r--r-- | app/models/repository.rb | 19 | ||||
-rw-r--r-- | app/models/tree.rb | 51 |
2 files changed, 43 insertions, 27 deletions
diff --git a/app/models/repository.rb b/app/models/repository.rb index 6ce480c32c4..37a1dd64052 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -487,7 +487,20 @@ class Repository end def blob_at(sha, path) - Blob.decorate(raw_repository.blob_at(sha, path), project) + blob = Blob.decorate(raw_repository.blob_at(sha, path), project) + + # Don't attempt to return a special result if there is no blob at all + return unless blob + + # Don't attempt to return a special result unless we're looking at HEAD + return blob unless head_commit&.sha == sha + + case path + when head_tree&.readme_path + ReadmeBlob.new(blob, self) + else + blob + end rescue Gitlab::Git::Repository::NoRepository nil end @@ -569,9 +582,7 @@ class Repository cache_method :merge_request_template_names, fallback: [] def readme - if readme = tree(:head)&.readme - ReadmeBlob.new(readme, self) - end + head_tree&.readme end def rendered_readme diff --git a/app/models/tree.rb b/app/models/tree.rb index 3641c33254c..cd385872171 100644 --- a/app/models/tree.rb +++ b/app/models/tree.rb @@ -2,6 +2,7 @@ class Tree include Gitlab::MarkupHelper + include Gitlab::Utils::StrongMemoize attr_accessor :repository, :sha, :path, :entries @@ -16,32 +17,36 @@ class Tree @entries = Gitlab::Git::Tree.where(git_repo, @sha, @path, recursive) end - def readme - return @readme if defined?(@readme) - - available_readmes = blobs.select do |blob| - Gitlab::FileDetector.type_of(blob.name) == :readme - end - - previewable_readmes = available_readmes.select do |blob| - previewable?(blob.name) - end - - plain_readmes = available_readmes.select do |blob| - plain?(blob.name) + def readme_path + strong_memoize(:readme_path) do + available_readmes = blobs.select do |blob| + Gitlab::FileDetector.type_of(blob.name) == :readme + end + + previewable_readmes = available_readmes.select do |blob| + previewable?(blob.name) + end + + plain_readmes = available_readmes.select do |blob| + plain?(blob.name) + end + + # Prioritize previewable over plain readmes + entry = previewable_readmes.first || plain_readmes.first + next nil unless entry + + if path == '/' + entry.name + else + File.join(path, entry.name) + end end + end - # Prioritize previewable over plain readmes - readme_tree = previewable_readmes.first || plain_readmes.first - - # Return if we can't preview any of them - if readme_tree.nil? - return @readme = nil + def readme + strong_memoize(:readme) do + repository.blob_at(sha, readme_path) if readme_path end - - readme_path = path == '/' ? readme_tree.name : File.join(path, readme_tree.name) - - @readme = repository.blob_at(sha, readme_path) end def trees |