From 6580de78bb52323fcafaaf4d2e770590e4f1c586 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Thu, 6 Sep 2018 10:59:52 +0800 Subject: Add access to Blob's language from gitattributes Ported from Highlight class since it as a concept is more related to blob, and this allows more flexibility. --- lib/gitlab/search_results.rb | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index 5ce3eda2ccb..f2795c739f5 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -25,6 +25,12 @@ module Gitlab def no_highlighting? false end + + # Since search results often contain many items, + # not triggering lookup can avoid n+1 queries. + def language_from_gitattributes + nil + end end attr_reader :current_user, :query, :per_page -- cgit v1.2.1 From 32f9cf8ce3dd337bf3b1683c5872171c253f0d27 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Thu, 6 Sep 2018 17:48:57 +0800 Subject: Add BlobPresenter for highlighting Force FoundBlob to use BlobPresenter --- lib/gitlab/search_results.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib') diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index f2795c739f5..3dbb0608a4f 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -4,6 +4,7 @@ module Gitlab class SearchResults class FoundBlob include EncodingHelper + include Presentable attr_reader :id, :filename, :basename, :ref, :startline, :data, :project_id @@ -31,6 +32,10 @@ module Gitlab def language_from_gitattributes nil end + + def present + super(presenter_class: BlobPresenter) + end end attr_reader :current_user, :query, :per_page -- cgit v1.2.1 From 39ae9a59a59615092fbef189466f37c34f4a7fb1 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Thu, 6 Sep 2018 12:34:25 +0800 Subject: Make Highlight accept language param This replaces the repository param. This allows more flexiblity as sometimes we have highlight content not related to repository. Sometimes we know ahead of time the language of the content. Lastly language determination seems better fit as a logic in the Blob class. `repository` param is only used to determine the language, which seems to be the responsiblity of Blob. --- lib/gitlab/blame.rb | 3 +-- lib/gitlab/conflict/file.rb | 36 +++++++++++++++++++++++++++++++----- lib/gitlab/diff/highlight.rb | 2 +- lib/gitlab/highlight.rb | 14 ++++++-------- 4 files changed, 39 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/blame.rb b/lib/gitlab/blame.rb index 0d79594363e..f1a653a9d95 100644 --- a/lib/gitlab/blame.rb +++ b/lib/gitlab/blame.rb @@ -43,8 +43,7 @@ module Gitlab def highlighted_lines @blob.load_all_data! - @highlighted_lines ||= - Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: repository).lines + @highlighted_lines ||= @blob.present.highlight.lines end def project diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index 30911b49b18..501c2111530 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -3,6 +3,7 @@ module Gitlab class File include Gitlab::Routing include IconsHelper + include Gitlab::Utils::StrongMemoize CONTEXT_LINES = 3 @@ -30,11 +31,8 @@ module Gitlab end def highlight_lines! - their_file = lines.reject { |line| line.type == 'new' }.map(&:text).join("\n") - our_file = lines.reject { |line| line.type == 'old' }.map(&:text).join("\n") - - their_highlight = Gitlab::Highlight.highlight(their_path, their_file, repository: repository).lines - our_highlight = Gitlab::Highlight.highlight(our_path, our_file, repository: repository).lines + their_highlight = Gitlab::Highlight.highlight(their_path, their_lines, language: their_language).lines + our_highlight = Gitlab::Highlight.highlight(our_path, our_lines, language: our_language).lines lines.each do |line| line.rich_text = @@ -182,6 +180,34 @@ module Gitlab raw_line[:line_new], parent_file: self) end end + + def their_language + strong_memoize(:their_language) do + repository.gitattribute(their_path, 'gitlab-language') + end + end + + def our_language + strong_memoize(:our_language) do + if our_path == their_path + their_language + else + repository.gitattribute(our_path, 'gitlab-language') + end + end + end + + def their_lines + strong_memoize(:their_lines) do + lines.reject { |line| line.type == 'new' }.map(&:text).join("\n") + end + end + + def our_lines + strong_memoize(:our_lines) do + lines.reject { |line| line.type == 'old' }.map(&:text).join("\n") + end + end end end end diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index a605ddb5c33..1d833183ec3 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -79,7 +79,7 @@ module Gitlab return [] unless blob blob.load_all_data! - Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines + blob.present.highlight.lines end end end diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index 83095acc528..d28223194cc 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -5,16 +5,16 @@ module Gitlab TIMEOUT_BACKGROUND = 30.seconds TIMEOUT_FOREGROUND = 3.seconds - def self.highlight(blob_name, blob_content, repository: nil, plain: false) - new(blob_name, blob_content, repository: repository) + def self.highlight(blob_name, blob_content, language: nil, plain: false) + new(blob_name, blob_content, language: language) .highlight(blob_content, continue: false, plain: plain) end attr_reader :blob_name - def initialize(blob_name, blob_content, repository: nil) + def initialize(blob_name, blob_content, language: nil) @formatter = Rouge::Formatters::HTMLGitlab - @repository = repository + @language = language @blob_name = blob_name @blob_content = blob_content end @@ -36,11 +36,9 @@ module Gitlab private def custom_language - language_name = @repository && @repository.gitattribute(@blob_name, 'gitlab-language') + return nil unless @language - return nil unless language_name - - Rouge::Lexer.find_fancy(language_name) + Rouge::Lexer.find_fancy(@language) end def highlight_text(text, continue: true, plain: false) -- cgit v1.2.1 From bc14e4ed1024efa1e0a411bd59e1339fb1af20c0 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Tue, 11 Sep 2018 12:37:44 +0800 Subject: Move :plain option to Highlight class This is to DRY the repeated file size check. Move spec and constants to Highlight --- lib/gitlab/highlight.rb | 3 +++ lib/gitlab/search_results.rb | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index d28223194cc..a4e60bbd828 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -4,6 +4,7 @@ module Gitlab class Highlight TIMEOUT_BACKGROUND = 30.seconds TIMEOUT_FOREGROUND = 3.seconds + MAXIMUM_TEXT_HIGHLIGHT_SIZE = 1.megabyte def self.highlight(blob_name, blob_content, language: nil, plain: false) new(blob_name, blob_content, language: language) @@ -20,6 +21,8 @@ module Gitlab end def highlight(text, continue: true, plain: false) + plain ||= text.length > MAXIMUM_TEXT_HIGHLIGHT_SIZE + highlighted_text = highlight_text(text, continue: continue, plain: plain) highlighted_text = link_dependencies(text, highlighted_text) if blob_name highlighted_text diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index 3dbb0608a4f..6c86ad11385 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -23,10 +23,6 @@ module Gitlab filename end - def no_highlighting? - false - end - # Since search results often contain many items, # not triggering lookup can avoid n+1 queries. def language_from_gitattributes -- cgit v1.2.1 From a4ba973e24ef6767d635c0291c9b6ce8085aef28 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Thu, 4 Oct 2018 17:16:51 +0800 Subject: Allow FoundBlob to access language from gitattributes Extract language_from_git_attributes as a concern so it can ben included in two blob classes. --- lib/gitlab/project_search_results.rb | 2 +- lib/gitlab/search_results.rb | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/gitlab/project_search_results.rb b/lib/gitlab/project_search_results.rb index 3a202d915e3..04df881bf03 100644 --- a/lib/gitlab/project_search_results.rb +++ b/lib/gitlab/project_search_results.rb @@ -82,7 +82,7 @@ module Gitlab ref: ref, startline: startline, data: data.join, - project_id: project ? project.id : nil + project: project ) end diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index 6c86ad11385..b46c18c4364 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -5,8 +5,9 @@ module Gitlab class FoundBlob include EncodingHelper include Presentable + include BlobLanguageFromGitAttributes - attr_reader :id, :filename, :basename, :ref, :startline, :data, :project_id + attr_reader :id, :filename, :basename, :ref, :startline, :data, :project def initialize(opts = {}) @id = opts.fetch(:id, nil) @@ -16,17 +17,15 @@ module Gitlab @startline = opts.fetch(:startline, nil) @data = encode_utf8(opts.fetch(:data, nil)) @per_page = opts.fetch(:per_page, 20) - @project_id = opts.fetch(:project_id, nil) + @project = opts.fetch(:project, nil) end def path filename end - # Since search results often contain many items, - # not triggering lookup can avoid n+1 queries. - def language_from_gitattributes - nil + def project_id + @project&.id end def present -- cgit v1.2.1 From 0fa5260f1d1e99bcd0429cba09140c039a3d9d5a Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Tue, 16 Oct 2018 13:56:13 +0800 Subject: Allow search results to accept project_id This gives flexiblity to avoid duplicated query of Project. --- lib/gitlab/search_results.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/gitlab/search_results.rb b/lib/gitlab/search_results.rb index b46c18c4364..458737f31eb 100644 --- a/lib/gitlab/search_results.rb +++ b/lib/gitlab/search_results.rb @@ -18,6 +18,11 @@ module Gitlab @data = encode_utf8(opts.fetch(:data, nil)) @per_page = opts.fetch(:per_page, 20) @project = opts.fetch(:project, nil) + # Some caller does not have project object (e.g. elastic search), + # yet they can trigger many calls in one go, + # causing duplicated queries. + # Allow those to just pass project_id instead. + @project_id = opts.fetch(:project_id, nil) end def path @@ -25,7 +30,7 @@ module Gitlab end def project_id - @project&.id + @project_id || @project&.id end def present -- cgit v1.2.1