summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMarius Balteanu <marius.balteanu@zitec.com>2021-10-24 10:05:03 +0000
committerMarius Balteanu <marius.balteanu@zitec.com>2021-10-24 10:05:03 +0000
commit81273a9128f94420c9404eb6670412d758bcb768 (patch)
treef131215b66cde431659179b1e94c26500139d3d0 /lib
parentdcf69e509a9342f1c493303a8b0a4bee278e00b0 (diff)
downloadredmine-81273a9128f94420c9404eb6670412d758bcb768.tar.gz
redmine-81273a9128f94420c9404eb6670412d758bcb768.zip
Extract @Diff@ and @DiffTable@ from @lib/redmine/unified_diff.rb@ to their own files (#29914, #32938).
git-svn-id: http://svn.redmine.org/redmine/trunk@21259 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'lib')
-rw-r--r--lib/redmine/diff.rb92
-rw-r--r--lib/redmine/diff_table.rb190
-rw-r--r--lib/redmine/unified_diff.rb242
3 files changed, 282 insertions, 242 deletions
diff --git a/lib/redmine/diff.rb b/lib/redmine/diff.rb
new file mode 100644
index 000000000..046cdc3f1
--- /dev/null
+++ b/lib/redmine/diff.rb
@@ -0,0 +1,92 @@
+# frozen_string_literal: true
+
+# Redmine - project management software
+# Copyright (C) 2006-2021 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+module Redmine
+ # A line of diff
+ class Diff
+ attr_accessor :nb_line_left
+ attr_accessor :line_left
+ attr_accessor :nb_line_right
+ attr_accessor :line_right
+ attr_accessor :type_diff_right
+ attr_accessor :type_diff_left
+ attr_accessor :offsets
+
+ def initialize
+ self.nb_line_left = ''
+ self.nb_line_right = ''
+ self.line_left = ''
+ self.line_right = ''
+ self.type_diff_right = ''
+ self.type_diff_left = ''
+ end
+
+ def type_diff
+ type_diff_right == 'diff_in' ? type_diff_right : type_diff_left
+ end
+
+ def line
+ type_diff_right == 'diff_in' ? line_right : line_left
+ end
+
+ def html_line_left
+ line_to_html(line_left, offsets)
+ end
+
+ def html_line_right
+ line_to_html(line_right, offsets)
+ end
+
+ def html_line
+ line_to_html(line, offsets)
+ end
+
+ def inspect
+ puts '### Start Line Diff ###'
+ puts self.nb_line_left
+ puts self.line_left
+ puts self.nb_line_right
+ puts self.line_right
+ end
+
+ private
+
+ def line_to_html(line, offsets)
+ html = line_to_html_raw(line, offsets)
+ html.force_encoding('UTF-8')
+ html
+ end
+
+ def line_to_html_raw(line, offsets)
+ if offsets
+ s = +''
+ unless offsets.first == 0
+ s << CGI.escapeHTML(line[0..offsets.first-1])
+ end
+ s << '<span>' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '</span>'
+ unless offsets.last == -1
+ s << CGI.escapeHTML(line[offsets.last+1..-1])
+ end
+ s
+ else
+ CGI.escapeHTML(line)
+ end
+ end
+ end
+end
diff --git a/lib/redmine/diff_table.rb b/lib/redmine/diff_table.rb
new file mode 100644
index 000000000..ccac74b1e
--- /dev/null
+++ b/lib/redmine/diff_table.rb
@@ -0,0 +1,190 @@
+# frozen_string_literal: true
+
+# Redmine - project management software
+# Copyright (C) 2006-2021 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Class that represents a file diff
+module Redmine
+ class DiffTable < Array
+ attr_reader :file_name, :previous_file_name
+
+ # Initialize with a Diff file and the type of Diff View
+ # The type view must be inline or sbs (side_by_side)
+ def initialize(type="inline", style=nil)
+ @parsing = false
+ @added = 0
+ @removed = 0
+ @type = type
+ @style = style
+ @file_name = nil
+ @previous_file_name = nil
+ @git_diff = false
+ end
+
+ # Function for add a line of this Diff
+ # Returns false when the diff ends
+ def add_line(line)
+ unless @parsing
+ if line =~ /^(---|\+\+\+) (.*)$/
+ self.file_name = $2
+ elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+ @line_num_l = $2.to_i
+ @line_num_r = $5.to_i
+ @parsing = true
+ end
+ else
+ if %r{^[^\+\-\s@\\]}.match?(line)
+ @parsing = false
+ return false
+ elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+ @line_num_l = $2.to_i
+ @line_num_r = $5.to_i
+ else
+ parse_line(line, @type)
+ end
+ end
+ return true
+ end
+
+ def each_line
+ prev_line_left, prev_line_right = nil, nil
+ each do |line|
+ spacing = prev_line_left && prev_line_right && (line.nb_line_left != prev_line_left+1) && (line.nb_line_right != prev_line_right+1)
+ yield spacing, line
+ prev_line_left = line.nb_line_left.to_i if line.nb_line_left.to_i > 0
+ prev_line_right = line.nb_line_right.to_i if line.nb_line_right.to_i > 0
+ end
+ end
+
+ def inspect
+ puts '### DIFF TABLE ###'
+ puts "file : #{file_name}"
+ self.each do |d|
+ d.inspect
+ end
+ end
+
+ private
+
+ def file_name=(arg)
+ both_git_diff = false
+ if file_name.nil?
+ @git_diff = true if %r{^(a/|/dev/null)}.match?(arg)
+ else
+ both_git_diff = (@git_diff && %r{^(b/|/dev/null)}.match?(arg))
+ end
+ if both_git_diff
+ if file_name && arg == "/dev/null"
+ # keep the original file name
+ @file_name = file_name.sub(%r{^a/}, '')
+ else
+ # remove leading a/
+ @previous_file_name = file_name.sub(%r{^a/}, '') unless file_name == "/dev/null"
+ # remove leading b/
+ @file_name = arg.sub(%r{^b/}, '')
+
+ @previous_file_name = nil if @previous_file_name == @file_name
+ end
+ elsif @style == "Subversion"
+ # removing trailing "(revision nn)"
+ @file_name = arg.sub(%r{\t+\(.*\)$}, '')
+ else
+ @file_name = arg
+ end
+ end
+
+ def diff_for_added_line
+ if @type == 'sbs' && @removed > 0 && @added < @removed
+ self[-(@removed - @added)]
+ else
+ diff = Diff.new
+ self << diff
+ diff
+ end
+ end
+
+ def parse_line(line, type="inline")
+ if line[0, 1] == "+"
+ diff = diff_for_added_line
+ diff.line_right = line[1..-1]
+ diff.nb_line_right = @line_num_r
+ diff.type_diff_right = 'diff_in'
+ @line_num_r += 1
+ @added += 1
+ true
+ elsif line[0, 1] == "-"
+ diff = Diff.new
+ diff.line_left = line[1..-1]
+ diff.nb_line_left = @line_num_l
+ diff.type_diff_left = 'diff_out'
+ self << diff
+ @line_num_l += 1
+ @removed += 1
+ true
+ else
+ write_offsets
+ if /\s/.match?(line[0, 1])
+ diff = Diff.new
+ diff.line_right = line[1..-1]
+ diff.nb_line_right = @line_num_r
+ diff.line_left = line[1..-1]
+ diff.nb_line_left = @line_num_l
+ self << diff
+ @line_num_l += 1
+ @line_num_r += 1
+ true
+ elsif line[0, 1] = "\\"
+ true
+ else
+ false
+ end
+ end
+ end
+
+ def write_offsets
+ if @added > 0 && @added == @removed
+ @added.times do |i|
+ line = self[-(1 + i)]
+ removed = (@type == 'sbs') ? line : self[-(1 + @added + i)]
+ offsets = offsets(removed.line_left, line.line_right)
+ removed.offsets = line.offsets = offsets
+ end
+ end
+ @added = 0
+ @removed = 0
+ end
+
+ def offsets(line_left, line_right)
+ if line_left.present? && line_right.present? && line_left != line_right
+ max = [line_left.size, line_right.size].min
+ starting = 0
+ while starting < max &&
+ line_left[starting] == line_right[starting]
+ starting += 1
+ end
+ ending = -1
+ while ending >= -(max - starting) &&
+ (line_left[ending] == line_right[ending])
+ ending -= 1
+ end
+ unless starting == 0 && ending == -1
+ [starting, ending]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb
index f82d37620..16984016f 100644
--- a/lib/redmine/unified_diff.rb
+++ b/lib/redmine/unified_diff.rb
@@ -54,246 +54,4 @@ module Redmine
def truncated?; @truncated; end
end
-
- # Class that represents a file diff
- class DiffTable < Array
- attr_reader :file_name, :previous_file_name
-
- # Initialize with a Diff file and the type of Diff View
- # The type view must be inline or sbs (side_by_side)
- def initialize(type="inline", style=nil)
- @parsing = false
- @added = 0
- @removed = 0
- @type = type
- @style = style
- @file_name = nil
- @previous_file_name = nil
- @git_diff = false
- end
-
- # Function for add a line of this Diff
- # Returns false when the diff ends
- def add_line(line)
- unless @parsing
- if line =~ /^(---|\+\+\+) (.*)$/
- self.file_name = $2
- elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
- @line_num_l = $2.to_i
- @line_num_r = $5.to_i
- @parsing = true
- end
- else
- if %r{^[^\+\-\s@\\]}.match?(line)
- @parsing = false
- return false
- elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
- @line_num_l = $2.to_i
- @line_num_r = $5.to_i
- else
- parse_line(line, @type)
- end
- end
- return true
- end
-
- def each_line
- prev_line_left, prev_line_right = nil, nil
- each do |line|
- spacing = prev_line_left && prev_line_right && (line.nb_line_left != prev_line_left+1) && (line.nb_line_right != prev_line_right+1)
- yield spacing, line
- prev_line_left = line.nb_line_left.to_i if line.nb_line_left.to_i > 0
- prev_line_right = line.nb_line_right.to_i if line.nb_line_right.to_i > 0
- end
- end
-
- def inspect
- puts '### DIFF TABLE ###'
- puts "file : #{file_name}"
- self.each do |d|
- d.inspect
- end
- end
-
- private
-
- def file_name=(arg)
- both_git_diff = false
- if file_name.nil?
- @git_diff = true if %r{^(a/|/dev/null)}.match?(arg)
- else
- both_git_diff = (@git_diff && %r{^(b/|/dev/null)}.match?(arg))
- end
- if both_git_diff
- if file_name && arg == "/dev/null"
- # keep the original file name
- @file_name = file_name.sub(%r{^a/}, '')
- else
- # remove leading a/
- @previous_file_name = file_name.sub(%r{^a/}, '') unless file_name == "/dev/null"
- # remove leading b/
- @file_name = arg.sub(%r{^b/}, '')
-
- @previous_file_name = nil if @previous_file_name == @file_name
- end
- elsif @style == "Subversion"
- # removing trailing "(revision nn)"
- @file_name = arg.sub(%r{\t+\(.*\)$}, '')
- else
- @file_name = arg
- end
- end
-
- def diff_for_added_line
- if @type == 'sbs' && @removed > 0 && @added < @removed
- self[-(@removed - @added)]
- else
- diff = Diff.new
- self << diff
- diff
- end
- end
-
- def parse_line(line, type="inline")
- if line[0, 1] == "+"
- diff = diff_for_added_line
- diff.line_right = line[1..-1]
- diff.nb_line_right = @line_num_r
- diff.type_diff_right = 'diff_in'
- @line_num_r += 1
- @added += 1
- true
- elsif line[0, 1] == "-"
- diff = Diff.new
- diff.line_left = line[1..-1]
- diff.nb_line_left = @line_num_l
- diff.type_diff_left = 'diff_out'
- self << diff
- @line_num_l += 1
- @removed += 1
- true
- else
- write_offsets
- if /\s/.match?(line[0, 1])
- diff = Diff.new
- diff.line_right = line[1..-1]
- diff.nb_line_right = @line_num_r
- diff.line_left = line[1..-1]
- diff.nb_line_left = @line_num_l
- self << diff
- @line_num_l += 1
- @line_num_r += 1
- true
- elsif line[0, 1] = "\\"
- true
- else
- false
- end
- end
- end
-
- def write_offsets
- if @added > 0 && @added == @removed
- @added.times do |i|
- line = self[-(1 + i)]
- removed = (@type == 'sbs') ? line : self[-(1 + @added + i)]
- offsets = offsets(removed.line_left, line.line_right)
- removed.offsets = line.offsets = offsets
- end
- end
- @added = 0
- @removed = 0
- end
-
- def offsets(line_left, line_right)
- if line_left.present? && line_right.present? && line_left != line_right
- max = [line_left.size, line_right.size].min
- starting = 0
- while starting < max &&
- line_left[starting] == line_right[starting]
- starting += 1
- end
- ending = -1
- while ending >= -(max - starting) &&
- (line_left[ending] == line_right[ending])
- ending -= 1
- end
- unless starting == 0 && ending == -1
- [starting, ending]
- end
- end
- end
- end
-
- # A line of diff
- class Diff
- attr_accessor :nb_line_left
- attr_accessor :line_left
- attr_accessor :nb_line_right
- attr_accessor :line_right
- attr_accessor :type_diff_right
- attr_accessor :type_diff_left
- attr_accessor :offsets
-
- def initialize
- self.nb_line_left = ''
- self.nb_line_right = ''
- self.line_left = ''
- self.line_right = ''
- self.type_diff_right = ''
- self.type_diff_left = ''
- end
-
- def type_diff
- type_diff_right == 'diff_in' ? type_diff_right : type_diff_left
- end
-
- def line
- type_diff_right == 'diff_in' ? line_right : line_left
- end
-
- def html_line_left
- line_to_html(line_left, offsets)
- end
-
- def html_line_right
- line_to_html(line_right, offsets)
- end
-
- def html_line
- line_to_html(line, offsets)
- end
-
- def inspect
- puts '### Start Line Diff ###'
- puts self.nb_line_left
- puts self.line_left
- puts self.nb_line_right
- puts self.line_right
- end
-
- private
-
- def line_to_html(line, offsets)
- html = line_to_html_raw(line, offsets)
- html.force_encoding('UTF-8')
- html
- end
-
- def line_to_html_raw(line, offsets)
- if offsets
- s = +''
- unless offsets.first == 0
- s << CGI.escapeHTML(line[0..offsets.first-1])
- end
- s << '<span>' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '</span>'
- unless offsets.last == -1
- s << CGI.escapeHTML(line[offsets.last+1..-1])
- end
- s
- else
- CGI.escapeHTML(line)
- end
- end
- end
end