Skip to content
Snippets Groups Projects
Commit 21b602c6 authored by Rubén Dávila's avatar Rubén Dávila
Browse files

Change strategy to highlight diffs. #3945

Now we apply syntax highlighting to the whole old and new files.
This basically help us to highlight adequately multiline content.
parent f1f4fdf7
No related branches found
No related tags found
No related merge requests found
Showing
with 76 additions and 29 deletions
Loading
@@ -24,6 +24,7 @@ class ApplicationController < ActionController::Base
Loading
@@ -24,6 +24,7 @@ class ApplicationController < ActionController::Base
   
helper_method :abilities, :can?, :current_application_settings helper_method :abilities, :can?, :current_application_settings
helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled? helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
helper_method :repository
   
rescue_from Encoding::CompatibilityError do |exception| rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception) log_exception(exception)
Loading
Loading
Loading
@@ -65,8 +65,11 @@ class Projects::BlobController < Projects::ApplicationController
Loading
@@ -65,8 +65,11 @@ class Projects::BlobController < Projects::ApplicationController
end end
   
def diff def diff
@form = UnfoldForm.new(params) ref, file_name = params[:id].split('/', 2)
@lines = Gitlab::Diff::Highlight.process_diff_lines(@blob.name, @blob.data.lines[@form.since - 1..@form.to - 1])
@form = UnfoldForm.new(params)
@lines = Gitlab::Diff::Highlight.process_file(repository, ref, file_name)
@lines = @lines[@form.since - 1..@form.to - 1]
   
if @form.bottom? if @form.bottom?
@match_line = '' @match_line = ''
Loading
Loading
Loading
@@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
Loading
@@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
@diffs = commit.diffs @diffs = commit.diffs
end end
   
@diff_refs = [commit.parent.id, commit.id]
@notes_count = commit.notes.count @notes_count = commit.notes.count
   
@statuses = ci_commit.statuses if ci_commit @statuses = ci_commit.statuses if ci_commit
Loading
Loading
Loading
@@ -20,6 +20,7 @@ class Projects::CompareController < Projects::ApplicationController
Loading
@@ -20,6 +20,7 @@ class Projects::CompareController < Projects::ApplicationController
if compare_result if compare_result
@commits = Commit.decorate(compare_result.commits, @project) @commits = Commit.decorate(compare_result.commits, @project)
@diffs = compare_result.diffs @diffs = compare_result.diffs
@diff_refs = [base_ref, head_ref]
@commit = @project.commit(head_ref) @commit = @project.commit(head_ref)
@first_commit = @project.commit(base_ref) @first_commit = @project.commit(base_ref)
@line_notes = [] @line_notes = []
Loading
Loading
Loading
@@ -59,6 +59,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
Loading
@@ -59,6 +59,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def diffs def diffs
@commit = @merge_request.last_commit @commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit @first_commit = @merge_request.first_commit
@diff_refs = [@merge_request.target_sha, @merge_request.source_sha]
   
@comments_allowed = @reply_allowed = true @comments_allowed = @reply_allowed = true
@comments_target = { @comments_target = {
Loading
@@ -103,6 +104,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
Loading
@@ -103,6 +104,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commit = @merge_request.last_commit @commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit @first_commit = @merge_request.first_commit
@diffs = @merge_request.compare_diffs @diffs = @merge_request.compare_diffs
@diff_refs = [@merge_request.target_sha, @merge_request.source_branch]
   
@ci_commit = @merge_request.ci_commit @ci_commit = @merge_request.ci_commit
@statuses = @ci_commit.statuses if @ci_commit @statuses = @ci_commit.statuses if @ci_commit
Loading
Loading
Loading
@@ -19,13 +19,13 @@ module DiffHelper
Loading
@@ -19,13 +19,13 @@ module DiffHelper
end end
end end
   
def safe_diff_files(diffs) def safe_diff_files(diffs, diff_refs, repository)
lines = 0 lines = 0
safe_files = [] safe_files = []
diffs.first(allowed_diff_size).each do |diff| diffs.first(allowed_diff_size).each do |diff|
lines += diff.diff.lines.count lines += diff.diff.lines.count
break if lines > allowed_diff_lines break if lines > allowed_diff_lines
safe_files << Gitlab::Diff::File.new(diff) safe_files << Gitlab::Diff::File.new(diff, diff_refs, repository)
end end
safe_files safe_files
end end
Loading
Loading
Loading
@@ -5,5 +5,6 @@
Loading
@@ -5,5 +5,6 @@
= render "ci_menu" = render "ci_menu"
- else - else
%div.block-connector %div.block-connector
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project,
diff_refs: @diff_refs
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
Loading
@@ -9,7 +9,7 @@
Loading
@@ -9,7 +9,7 @@
- if @commits.present? - if @commits.present?
.prepend-top-default .prepend-top-default
= render "projects/commits/commit_list" = render "projects/commits/commit_list"
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
- else - else
.light-well.prepend-top-default .light-well.prepend-top-default
.center .center
Loading
Loading
- if diff_view == 'parallel' - if diff_view == 'parallel'
- fluid_layout true - fluid_layout true
   
- diff_files = safe_diff_files(diffs) - diff_files = safe_diff_files(diffs, diff_refs, repository)
   
.gray-content-block.middle-block.oneline-block .gray-content-block.middle-block.oneline-block
.inline-parallel-buttons .inline-parallel-buttons
Loading
Loading
Loading
@@ -38,7 +38,7 @@
Loading
@@ -38,7 +38,7 @@
= render "projects/merge_requests/show/commits" = render "projects/merge_requests/show/commits"
#diffs.diffs.tab-pane.active #diffs.diffs.tab-pane.active
- if @diffs.present? - if @diffs.present?
= render "projects/diffs/diffs", diffs: @diffs, project: @project = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
.alert.alert-danger .alert.alert-danger
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits. %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
Loading
Loading
- if @merge_request_diff.collected? - if @merge_request_diff.collected?
= render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs, project: @merge_request.project = render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs, project: @merge_request.project, diff_refs: @diff_refs
- elsif @merge_request_diff.empty? - elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else - else
Loading
Loading
module Gitlab module Gitlab
module Diff module Diff
class File class File
attr_reader :diff attr_reader :diff, :repository, :new_ref, :old_ref
   
delegate :new_file, :deleted_file, :renamed_file, delegate :new_file, :deleted_file, :renamed_file,
:old_path, :new_path, to: :diff, prefix: false :old_path, :new_path, to: :diff, prefix: false
   
def initialize(diff) def initialize(diff, diff_refs, repository)
@diff = diff @diff = diff
@repository = repository
@old_ref, @new_ref = diff_refs
end end
   
# Array of Gitlab::DIff::Line objects # Array of Gitlab::DIff::Line objects
Loading
@@ -16,7 +18,7 @@ module Gitlab
Loading
@@ -16,7 +18,7 @@ module Gitlab
end end
   
def highlighted_diff_lines def highlighted_diff_lines
Gitlab::Diff::Highlight.process_diff_lines(new_path, diff_lines) Gitlab::Diff::Highlight.process_diff_lines(self)
end end
   
def mode_changed? def mode_changed?
Loading
Loading
module Gitlab module Gitlab
module Diff module Diff
class Highlight class Highlight
attr_reader :diff_file
delegate :repository, :old_path, :new_path, :old_ref, :new_ref,
to: :diff_file, prefix: :diff
# Apply syntax highlight to provided source code # Apply syntax highlight to provided source code
# #
# file_name - The file name related to the code. # diff_file - an instance of Gitlab::Diff::File
# lines - It can be an Array of Gitlab::Diff::Line objects or simple Strings.
# When passing Strings you need to provide the required 'end of lines'
# chars ("\n") for each String given that we don't append them automatically.
# #
# Returns an Array with the processed items. # Returns an Array with the processed items.
def self.process_diff_lines(file_name, lines) def self.process_diff_lines(diff_file)
processor = new(file_name, lines) processor = new(diff_file)
processor.highlight processor.highlight
end end
   
def initialize(file_name, lines) def self.process_file(repository, ref, file_name)
@file_name = file_name blob = repository.blob_at(ref, file_name)
@lines = lines return [] unless blob
content = blob.data
lexer = Rouge::Lexer.guess(filename: file_name, source: content).new rescue Rouge::Lexers::PlainText.new
formatter.format(lexer.lex(content)).lines
end
def self.formatter
@formatter ||= Rouge::Formatters::HTMLGitlab.new(
nowrap: true,
cssclass: 'code highlight',
lineanchors: true,
lineanchorsid: 'LC'
)
end
def initialize(diff_file)
@diff_file = diff_file
@file_name = diff_file.new_path
@lines = diff_file.diff_lines
end end
   
def highlight def highlight
Loading
@@ -47,7 +68,7 @@ module Gitlab
Loading
@@ -47,7 +68,7 @@ module Gitlab
def extract_line_prefixes def extract_line_prefixes
@diff_line_prefixes ||= begin @diff_line_prefixes ||= begin
if is_diff_line? if is_diff_line?
text_lines.map { |line| line.sub!(/\A((\+|\-)\s*)/, '');$1 } text_lines.map { |line| line.sub!(/\A((\+|\-))/, '');$1 }
else else
[] []
end end
Loading
@@ -57,11 +78,17 @@ module Gitlab
Loading
@@ -57,11 +78,17 @@ module Gitlab
def update_diff_lines def update_diff_lines
@highlighted_code.lines.each_with_index do |line, i| @highlighted_code.lines.each_with_index do |line, i|
diff_line = @lines[i] diff_line = @lines[i]
line_prefix = @diff_line_prefixes[i] || ' '
   
# ignore highlighting for "match" lines # ignore highlighting for "match" lines
next if diff_line.type == 'match' next if diff_line.type == 'match'
   
diff_line.text = "#{@diff_line_prefixes[i]}#{line}" case diff_line.type
when 'new', nil
diff_line.text = new_lines[diff_line.new_pos - 1].try(:gsub!, /\A\s/, line_prefix)
when 'old'
diff_line.text = old_lines[diff_line.old_pos - 1].try(:gsub!, /\A\s/, line_prefix)
end
end end
   
@lines @lines
Loading
@@ -79,12 +106,21 @@ module Gitlab
Loading
@@ -79,12 +106,21 @@ module Gitlab
end end
   
def formatter def formatter
Rouge::Formatters::HTMLGitlab.new( self.class.formatter
nowrap: true, end
cssclass: 'code highlight',
lineanchors: true, def old_lines
lineanchorsid: 'LC' @old_lines ||= begin
) lines = self.class.process_file(diff_repository, diff_old_ref, diff_old_path)
lines.map! { |line| " #{line}" }
end
end
def new_lines
@new_lines ||= begin
lines = self.class.process_file(diff_repository, diff_new_ref, diff_new_path)
lines.map! { |line| " #{line}" }
end
end end
end end
end end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment