summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2016-01-20 14:51:56 +0100
committerDouwe Maan <douwe@gitlab.com>2016-01-20 14:53:20 +0100
commit701513dcc7afb403372bc738642a9a52e9be5983 (patch)
treef2eb3cf87de08bbfdfb22d67de7112616b766426 /lib
parentc7264d2a76abdc9d173e2160e27974d41380e93f (diff)
downloadgitlab-ce-701513dcc7afb403372bc738642a9a52e9be5983.tar.gz
Move parallel diff logic to separate class
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/diff/file.rb4
-rw-r--r--lib/gitlab/diff/parallel_diff.rb117
2 files changed, 121 insertions, 0 deletions
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index a6a7fc8ff4c..74b1c117129 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -20,6 +20,10 @@ module Gitlab
Gitlab::Diff::Highlight.new(self).highlight
end
+ def parallel_diff_lines
+ Gitlab::Diff::ParallelDiff.new(self).parallelize
+ end
+
def mode_changed?
!!(diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode)
end
diff --git a/lib/gitlab/diff/parallel_diff.rb b/lib/gitlab/diff/parallel_diff.rb
new file mode 100644
index 00000000000..a0dc3da875d
--- /dev/null
+++ b/lib/gitlab/diff/parallel_diff.rb
@@ -0,0 +1,117 @@
+module Gitlab
+ module Diff
+ class ParallelDiff
+ attr_accessor :diff_file
+
+ def initialize(diff_file)
+ @diff_file = diff_file
+ end
+
+ def parallelize
+ lines = []
+ skip_next = false
+
+ diff_file.highlighted_diff_lines.each do |line|
+ full_line = line.text
+ type = line.type
+ line_code = generate_line_code(diff_file.file_path, line)
+ line_new = line.new_pos
+ line_old = line.old_pos
+
+ next_line = diff_file.next_line(line.index)
+
+ if next_line
+ next_line_code = generate_line_code(diff_file.file_path, next_line)
+ next_type = next_line.type
+ next_line = next_line.text
+ end
+
+ case type
+ when 'match', nil
+ # line in the right panel is the same as in the left one
+ lines << {
+ left: {
+ type: type,
+ number: line_old,
+ text: full_line,
+ line_code: line_code,
+ },
+ right: {
+ type: type,
+ number: line_new,
+ text: full_line,
+ line_code: line_code
+ }
+ }
+ when 'old'
+ case next_type
+ when 'new'
+ # Left side has text removed, right side has text added
+ lines << {
+ left: {
+ type: type,
+ number: line_old,
+ text: full_line,
+ line_code: line_code,
+ },
+ right: {
+ type: next_type,
+ number: line_new,
+ text: next_line,
+ line_code: next_line_code
+ }
+ }
+ skip_next = true
+ when 'old', nil
+ # Left side has text removed, right side doesn't have any change
+ # No next line code, no new line number, no new line text
+ lines << {
+ left: {
+ type: type,
+ number: line_old,
+ text: full_line,
+ line_code: line_code,
+ },
+ right: {
+ type: next_type,
+ number: nil,
+ text: "",
+ line_code: nil
+ }
+ }
+ end
+ when 'new'
+ if skip_next
+ # Change has been already included in previous line so no need to do it again
+ skip_next = false
+ next
+ else
+ # Change is only on the right side, left side has no change
+ lines << {
+ left: {
+ type: nil,
+ number: nil,
+ text: "",
+ line_code: line_code,
+ },
+ right: {
+ type: type,
+ number: line_new,
+ text: full_line,
+ line_code: line_code
+ }
+ }
+ end
+ end
+ end
+ lines
+ end
+
+ private
+
+ def generate_line_code(file_path, line)
+ Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
+ end
+ end
+ end
+end