summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2008-06-08 16:28:42 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2008-06-08 16:28:42 +0000
commitec0525d4975b9cae9982695cb0a19ac9c4bd1a3c (patch)
treed1f1afa7c69e6fde7c830f338b34fc49d4af56a2 /lib
parent731d15fe9b29a28362fff19ed7dad9df2516d73b (diff)
downloadredmine-ec0525d4975b9cae9982695cb0a19ac9c4bd1a3c.tar.gz
redmine-ec0525d4975b9cae9982695cb0a19ac9c4bd1a3c.zip
Move unified diff parser out of the scm abstract adapter so it can be reused for viewing attached diffs (#1403).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1513 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'lib')
-rw-r--r--lib/redmine/scm/adapters/abstract_adapter.rb161
-rw-r--r--lib/redmine/scm/adapters/bazaar_adapter.rb4
-rw-r--r--lib/redmine/scm/adapters/cvs_adapter.rb4
-rw-r--r--lib/redmine/scm/adapters/darcs_adapter.rb4
-rw-r--r--lib/redmine/scm/adapters/git_adapter.rb4
-rw-r--r--lib/redmine/scm/adapters/mercurial_adapter.rb4
-rw-r--r--lib/redmine/scm/adapters/subversion_adapter.rb2
-rw-r--r--lib/redmine/unified_diff.rb178
8 files changed, 190 insertions, 171 deletions
diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb
index bd77ce203..0bacda770 100644
--- a/lib/redmine/scm/adapters/abstract_adapter.rb
+++ b/lib/redmine/scm/adapters/abstract_adapter.rb
@@ -82,7 +82,7 @@ module Redmine
return nil
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
return nil
end
@@ -234,166 +234,7 @@ module Redmine
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
- 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 inspect
- puts '### Start Line Diff ###'
- puts self.nb_line_left
- puts self.line_left
- puts self.nb_line_right
- puts self.line_right
- end
- end
-
- class DiffTableList < Array
- def initialize (diff, type="inline")
- diff_table = DiffTable.new type
- diff.each do |line|
- if line =~ /^(---|\+\+\+) (.*)$/
- self << diff_table if diff_table.length > 1
- diff_table = DiffTable.new type
- end
- a = diff_table.add_line line
- end
- self << diff_table unless diff_table.empty?
- self
- end
- end
-
- # Class for create a Diff
- class DiffTable < Hash
- attr_reader :file_name, :line_num_l, :line_num_r
-
- # 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")
- @parsing = false
- @nb_line = 1
- @start = false
- @before = 'same'
- @second = true
- @type = type
- end
-
- # Function for add a line of this Diff
- def add_line(line)
- unless @parsing
- if line =~ /^(---|\+\+\+) (.*)$/
- @file_name = $2
- return false
- elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
- @line_num_l = $5.to_i
- @line_num_r = $2.to_i
- @parsing = true
- end
- else
- if line =~ /^[^\+\-\s@\\]/
- @parsing = false
- return false
- elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
- @line_num_l = $5.to_i
- @line_num_r = $2.to_i
- else
- @nb_line += 1 if parse_line(line, @type)
- end
- end
- return true
- end
-
- def inspect
- puts '### DIFF TABLE ###'
- puts "file : #{file_name}"
- self.each do |d|
- d.inspect
- end
- end
-
- private
- # Test if is a Side By Side type
- def sbs?(type, func)
- if @start and type == "sbs"
- if @before == func and @second
- tmp_nb_line = @nb_line
- self[tmp_nb_line] = Diff.new
- else
- @second = false
- tmp_nb_line = @start
- @start += 1
- @nb_line -= 1
- end
- else
- tmp_nb_line = @nb_line
- @start = @nb_line
- self[tmp_nb_line] = Diff.new
- @second = true
- end
- unless self[tmp_nb_line]
- @nb_line += 1
- self[tmp_nb_line] = Diff.new
- else
- self[tmp_nb_line]
- end
- end
-
- # Escape the HTML for the diff
- def escapeHTML(line)
- CGI.escapeHTML(line)
- end
-
- def parse_line(line, type="inline")
- if line[0, 1] == "+"
- diff = sbs? type, 'add'
- @before = 'add'
- diff.line_left = escapeHTML line[1..-1]
- diff.nb_line_left = @line_num_l
- diff.type_diff_left = 'diff_in'
- @line_num_l += 1
- true
- elsif line[0, 1] == "-"
- diff = sbs? type, 'remove'
- @before = 'remove'
- diff.line_right = escapeHTML line[1..-1]
- diff.nb_line_right = @line_num_r
- diff.type_diff_right = 'diff_out'
- @line_num_r += 1
- true
- elsif line[0, 1] =~ /\s/
- @before = 'same'
- @start = false
- diff = Diff.new
- diff.line_right = escapeHTML line[1..-1]
- diff.nb_line_right = @line_num_r
- diff.line_left = escapeHTML line[1..-1]
- diff.nb_line_left = @line_num_l
- self[@nb_line] = diff
- @line_num_l += 1
- @line_num_r += 1
- true
- elsif line[0, 1] = "\\"
- true
- else
- false
- end
- end
- end
-
class Annotate
attr_reader :lines, :revisions
diff --git a/lib/redmine/scm/adapters/bazaar_adapter.rb b/lib/redmine/scm/adapters/bazaar_adapter.rb
index 2225a627c..ff69e3e6b 100644
--- a/lib/redmine/scm/adapters/bazaar_adapter.rb
+++ b/lib/redmine/scm/adapters/bazaar_adapter.rb
@@ -132,7 +132,7 @@ module Redmine
revisions
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
path ||= ''
if identifier_to
identifier_to = identifier_to.to_i
@@ -147,7 +147,7 @@ module Redmine
end
end
#return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
def cat(path, identifier=nil)
diff --git a/lib/redmine/scm/adapters/cvs_adapter.rb b/lib/redmine/scm/adapters/cvs_adapter.rb
index 37920b599..c86b02cb7 100644
--- a/lib/redmine/scm/adapters/cvs_adapter.rb
+++ b/lib/redmine/scm/adapters/cvs_adapter.rb
@@ -227,7 +227,7 @@ module Redmine
end
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{path_with_project}"
@@ -238,7 +238,7 @@ module Redmine
end
end
return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
def cat(path, identifier=nil)
diff --git a/lib/redmine/scm/adapters/darcs_adapter.rb b/lib/redmine/scm/adapters/darcs_adapter.rb
index a1d1867b1..b1b2a4573 100644
--- a/lib/redmine/scm/adapters/darcs_adapter.rb
+++ b/lib/redmine/scm/adapters/darcs_adapter.rb
@@ -94,7 +94,7 @@ module Redmine
revisions
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
path = '*' if path.blank?
cmd = "#{DARCS_BIN} diff --repodir #{@url}"
if identifier_to.nil?
@@ -111,7 +111,7 @@ module Redmine
end
end
return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
private
diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb
index 9dfbd17a8..d05b4fb38 100644
--- a/lib/redmine/scm/adapters/git_adapter.rb
+++ b/lib/redmine/scm/adapters/git_adapter.rb
@@ -204,7 +204,7 @@ module Redmine
revisions
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
path ||= ''
if !identifier_to
identifier_to = nil
@@ -220,7 +220,7 @@ module Redmine
end
end
return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
def annotate(path, identifier=nil)
diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb
index be01b7bbc..28b842c27 100644
--- a/lib/redmine/scm/adapters/mercurial_adapter.rb
+++ b/lib/redmine/scm/adapters/mercurial_adapter.rb
@@ -117,7 +117,7 @@ module Redmine
revisions
end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+ def diff(path, identifier_from, identifier_to=nil)
path ||= ''
if identifier_to
identifier_to = identifier_to.to_i
@@ -133,7 +133,7 @@ module Redmine
end
end
return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
def cat(path, identifier=nil)
diff --git a/lib/redmine/scm/adapters/subversion_adapter.rb b/lib/redmine/scm/adapters/subversion_adapter.rb
index 1cbdce135..7c98eee8b 100644
--- a/lib/redmine/scm/adapters/subversion_adapter.rb
+++ b/lib/redmine/scm/adapters/subversion_adapter.rb
@@ -142,7 +142,7 @@ module Redmine
end
end
return nil if $? && $?.exitstatus != 0
- DiffTableList.new diff, type
+ diff
end
def cat(path, identifier=nil)
diff --git a/lib/redmine/unified_diff.rb b/lib/redmine/unified_diff.rb
new file mode 100644
index 000000000..aa8994454
--- /dev/null
+++ b/lib/redmine/unified_diff.rb
@@ -0,0 +1,178 @@
+# redMine - project management software
+# Copyright (C) 2006-2008 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
+ # Class used to parse unified diffs
+ class UnifiedDiff < Array
+ def initialize(diff, type="inline")
+ diff_table = DiffTable.new type
+ diff.each do |line|
+ if line =~ /^(---|\+\+\+) (.*)$/
+ self << diff_table if diff_table.length > 1
+ diff_table = DiffTable.new type
+ end
+ a = diff_table.add_line line
+ end
+ self << diff_table unless diff_table.empty?
+ self
+ end
+ end
+
+ # Class that represents a file diff
+ class DiffTable < Hash
+ attr_reader :file_name, :line_num_l, :line_num_r
+
+ # 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")
+ @parsing = false
+ @nb_line = 1
+ @start = false
+ @before = 'same'
+ @second = true
+ @type = type
+ end
+
+ # Function for add a line of this Diff
+ def add_line(line)
+ unless @parsing
+ if line =~ /^(---|\+\+\+) (.*)$/
+ @file_name = $2
+ return false
+ elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+ @line_num_l = $5.to_i
+ @line_num_r = $2.to_i
+ @parsing = true
+ end
+ else
+ if line =~ /^[^\+\-\s@\\]/
+ @parsing = false
+ return false
+ elsif line =~ /^@@ (\+|\-)(\d+)(,\d+)? (\+|\-)(\d+)(,\d+)? @@/
+ @line_num_l = $5.to_i
+ @line_num_r = $2.to_i
+ else
+ @nb_line += 1 if parse_line(line, @type)
+ end
+ end
+ return true
+ end
+
+ def inspect
+ puts '### DIFF TABLE ###'
+ puts "file : #{file_name}"
+ self.each do |d|
+ d.inspect
+ end
+ end
+
+ private
+ # Test if is a Side By Side type
+ def sbs?(type, func)
+ if @start and type == "sbs"
+ if @before == func and @second
+ tmp_nb_line = @nb_line
+ self[tmp_nb_line] = Diff.new
+ else
+ @second = false
+ tmp_nb_line = @start
+ @start += 1
+ @nb_line -= 1
+ end
+ else
+ tmp_nb_line = @nb_line
+ @start = @nb_line
+ self[tmp_nb_line] = Diff.new
+ @second = true
+ end
+ unless self[tmp_nb_line]
+ @nb_line += 1
+ self[tmp_nb_line] = Diff.new
+ else
+ self[tmp_nb_line]
+ end
+ end
+
+ # Escape the HTML for the diff
+ def escapeHTML(line)
+ CGI.escapeHTML(line)
+ end
+
+ def parse_line(line, type="inline")
+ if line[0, 1] == "+"
+ diff = sbs? type, 'add'
+ @before = 'add'
+ diff.line_left = escapeHTML line[1..-1]
+ diff.nb_line_left = @line_num_l
+ diff.type_diff_left = 'diff_in'
+ @line_num_l += 1
+ true
+ elsif line[0, 1] == "-"
+ diff = sbs? type, 'remove'
+ @before = 'remove'
+ diff.line_right = escapeHTML line[1..-1]
+ diff.nb_line_right = @line_num_r
+ diff.type_diff_right = 'diff_out'
+ @line_num_r += 1
+ true
+ elsif line[0, 1] =~ /\s/
+ @before = 'same'
+ @start = false
+ diff = Diff.new
+ diff.line_right = escapeHTML line[1..-1]
+ diff.nb_line_right = @line_num_r
+ diff.line_left = escapeHTML line[1..-1]
+ diff.nb_line_left = @line_num_l
+ self[@nb_line] = diff
+ @line_num_l += 1
+ @line_num_r += 1
+ true
+ elsif line[0, 1] = "\\"
+ true
+ else
+ false
+ 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
+
+ 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 inspect
+ puts '### Start Line Diff ###'
+ puts self.nb_line_left
+ puts self.line_left
+ puts self.nb_line_right
+ puts self.line_right
+ end
+ end
+end