diff options
author | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2008-06-08 16:28:42 +0000 |
---|---|---|
committer | Jean-Philippe Lang <jp_lang@yahoo.fr> | 2008-06-08 16:28:42 +0000 |
commit | ec0525d4975b9cae9982695cb0a19ac9c4bd1a3c (patch) | |
tree | d1f1afa7c69e6fde7c830f338b34fc49d4af56a2 /lib | |
parent | 731d15fe9b29a28362fff19ed7dad9df2516d73b (diff) | |
download | redmine-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.rb | 161 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/bazaar_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/cvs_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/darcs_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/git_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/mercurial_adapter.rb | 4 | ||||
-rw-r--r-- | lib/redmine/scm/adapters/subversion_adapter.rb | 2 | ||||
-rw-r--r-- | lib/redmine/unified_diff.rb | 178 |
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 |