diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 4f53929a308..d8d14ea1fed 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -93,9 +93,11 @@ class Projects::BlobController < Projects::ApplicationController def diff apply_diff_view_cookie! - @form = UnfoldForm.new(params) - @lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path) - @lines = @lines[@form.since - 1..@form.to - 1] + @blob.load_all_data! + @lines = Gitlab::Highlight.highlight(@blob.path, @blob.data, repository: @repository).lines + + @form = UnfoldForm.new(params) + @lines = @lines[@form.since - 1..@form.to - 1].map(&:html_safe) if @form.bottom? @match_line = '' diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb index 2aef7fdaa35..374c5117517 100644 --- a/lib/gitlab/diff/file.rb +++ b/lib/gitlab/diff/file.rb @@ -58,19 +58,19 @@ module Gitlab diff_refs&.head_sha end - def content_sha - return old_content_sha if deleted_file? - return @content_sha if defined?(@content_sha) + def new_content_sha + return if deleted_file? + return @new_content_sha if defined?(@new_content_sha) refs = diff_refs || fallback_diff_refs - @content_sha = refs&.head_sha + @new_content_sha = refs&.head_sha end - def content_commit - return @content_commit if defined?(@content_commit) + def new_content_commit + return @new_content_commit if defined?(@new_content_commit) - sha = content_sha - @content_commit = repository.commit(sha) if sha + sha = new_content_commit + @new_content_commit = repository.commit(sha) if sha end def old_content_sha @@ -88,13 +88,13 @@ module Gitlab @old_content_commit = repository.commit(sha) if sha end - def blob - return @blob if defined?(@blob) + def new_blob + return @new_blob if defined?(@new_blob) - sha = content_sha - return @blob = nil unless sha + sha = new_content_sha + return @new_blob = nil unless sha - repository.blob_at(sha, file_path) + @new_blob = repository.blob_at(sha, file_path) end def old_blob @@ -106,6 +106,18 @@ module Gitlab @old_blob = repository.blob_at(sha, old_path) end + def content_sha + new_content_sha || old_content_sha + end + + def content_commit + new_content_commit || old_content_commit + end + + def blob + new_blob || old_blob + end + attr_writer :highlighted_diff_lines # Array of Gitlab::Diff::Line objects diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb index ed2f541977a..b669ee5b799 100644 --- a/lib/gitlab/diff/highlight.rb +++ b/lib/gitlab/diff/highlight.rb @@ -42,9 +42,9 @@ module Gitlab rich_line = if diff_line.unchanged? || diff_line.added? - new_lines[diff_line.new_pos - 1] + new_lines[diff_line.new_pos - 1]&.html_safe elsif diff_line.removed? - old_lines[diff_line.old_pos - 1] + old_lines[diff_line.old_pos - 1]&.html_safe end # Only update text if line is found. This will prevent @@ -60,13 +60,18 @@ module Gitlab end def old_lines - return unless diff_file - @old_lines ||= Gitlab::Highlight.highlight_lines(self.repository, diff_old_sha, diff_old_path) + @old_lines ||= highlighted_blob_lines(diff_file.old_blob) end def new_lines - return unless diff_file - @new_lines ||= Gitlab::Highlight.highlight_lines(self.repository, diff_new_sha, diff_new_path) + @new_lines ||= highlighted_blob_lines(diff_file.new_blob) + end + + def highlighted_blob_lines(blob) + return [] unless blob + + blob.load_all_data! + Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines end end end diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb index 23bc2f63c8e..6b24da030df 100644 --- a/lib/gitlab/highlight.rb +++ b/lib/gitlab/highlight.rb @@ -5,14 +5,6 @@ module Gitlab highlight(blob_content, continue: false, plain: plain) end - def self.highlight_lines(repository, ref, file_name) - blob = repository.blob_at(ref, file_name) - return [] unless blob - - blob.load_all_data! - highlight(file_name, blob.data, repository: repository).lines.map!(&:html_safe) - end - attr_reader :blob_name def initialize(blob_name, blob_content, repository: nil) diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb index a20cef3b000..c2bb9f9a166 100644 --- a/spec/lib/gitlab/highlight_spec.rb +++ b/spec/lib/gitlab/highlight_spec.rb @@ -7,30 +7,6 @@ describe Gitlab::Highlight, lib: true do let(:repository) { project.repository } let(:commit) { project.commit(sample_commit.id) } - describe '.highlight_lines' do - let(:lines) do - Gitlab::Highlight.highlight_lines(project.repository, commit.id, 'files/ruby/popen.rb') - end - - it 'highlights all the lines properly' do - expect(lines[4]).to eq(%Q{ extend self\n}) - expect(lines[21]).to eq(%Q{ unless File.directory?(path)\n}) - expect(lines[26]).to eq(%Q{ @cmd_status = 0\n}) - end - - describe 'with CRLF' do - let(:branch) { 'crlf-diff' } - let(:blob) { repository.blob_at_branch(branch, path) } - let(:lines) do - Gitlab::Highlight.highlight_lines(project.repository, 'crlf-diff', 'files/whitespace') - end - - it 'strips extra LFs' do - expect(lines[0]).to eq("test ") - end - end - end - describe 'custom highlighting from .gitattributes' do let(:branch) { 'gitattributes' } let(:blob) { repository.blob_at_branch(branch, path) } @@ -59,6 +35,19 @@ describe Gitlab::Highlight, lib: true do end describe '#highlight' do + describe 'with CRLF' do + let(:branch) { 'crlf-diff' } + let(:path) { 'files/whitespace' } + let(:blob) { repository.blob_at_branch(branch, path) } + let(:lines) do + Gitlab::Highlight.highlight(blob.path, blob.data, repository: repository).lines + end + + it 'strips extra LFs' do + expect(lines[0]).to eq("test ") + end + end + it 'links dependencies via DependencyLinker' do expect(Gitlab::DependencyLinker).to receive(:link). with('file.name', 'Contents', anything).and_call_original