diff-lcs 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +491 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +74 -0
- data/CONTRIBUTORS.md +48 -0
- data/Contributing.md +45 -90
- data/{License.md → LICENCE.md} +6 -4
- data/Manifest.txt +7 -4
- data/README.md +92 -0
- data/Rakefile +43 -66
- data/SECURITY.md +41 -0
- data/bin/htmldiff +4 -4
- data/docs/artistic.txt +1 -1
- data/lib/diff/lcs/array.rb +1 -1
- data/lib/diff/lcs/backports.rb +2 -2
- data/lib/diff/lcs/block.rb +4 -4
- data/lib/diff/lcs/callbacks.rb +9 -7
- data/lib/diff/lcs/change.rb +20 -20
- data/lib/diff/lcs/htmldiff.rb +26 -16
- data/lib/diff/lcs/hunk.rb +66 -45
- data/lib/diff/lcs/internals.rb +17 -17
- data/lib/diff/lcs/ldiff.rb +86 -74
- data/lib/diff/lcs.rb +66 -63
- data/lib/diff-lcs.rb +1 -1
- data/spec/change_spec.rb +50 -50
- data/spec/diff_spec.rb +14 -14
- data/spec/hunk_spec.rb +20 -20
- data/spec/issues_spec.rb +76 -70
- data/spec/lcs_spec.rb +11 -11
- data/spec/ldiff_spec.rb +30 -17
- data/spec/patch_spec.rb +84 -84
- data/spec/sdiff_spec.rb +111 -109
- data/spec/spec_helper.rb +76 -74
- data/spec/traverse_balanced_spec.rb +191 -189
- data/spec/traverse_sequences_spec.rb +31 -31
- metadata +55 -30
- data/Code-of-Conduct.md +0 -74
- data/History.md +0 -400
- data/README.rdoc +0 -84
data/lib/diff/lcs/backports.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
unless 0.respond_to?(:positive?)
|
4
|
-
class Fixnum #
|
4
|
+
class Fixnum # standard:disable Lint/UnifiedInteger
|
5
5
|
def positive?
|
6
|
-
self > 0
|
6
|
+
self > 0
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/diff/lcs/block.rb
CHANGED
@@ -25,13 +25,13 @@ class Diff::LCS::Block
|
|
25
25
|
def op
|
26
26
|
case [@remove.empty?, @insert.empty?]
|
27
27
|
when [false, false]
|
28
|
-
|
28
|
+
"!"
|
29
29
|
when [false, true]
|
30
|
-
|
30
|
+
"-"
|
31
31
|
when [true, false]
|
32
|
-
|
32
|
+
"+"
|
33
33
|
else # [true, true]
|
34
|
-
|
34
|
+
"^"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
data/lib/diff/lcs/callbacks.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/change"
|
4
4
|
|
5
|
-
module Diff::LCS
|
5
|
+
module Diff::LCS
|
6
6
|
# This callback object implements the default set of callback events,
|
7
7
|
# which only returns the event itself. Note that #finished_a and
|
8
8
|
# #finished_b are not implemented -- I haven't yet figured out where they
|
@@ -50,7 +50,9 @@ module Diff::LCS # rubocop:disable Style/Documentation
|
|
50
50
|
BalancedCallbacks = DefaultCallbacks
|
51
51
|
|
52
52
|
def self.callbacks_for(callbacks)
|
53
|
-
callbacks.new
|
53
|
+
callbacks.new
|
54
|
+
rescue
|
55
|
+
callbacks
|
54
56
|
end
|
55
57
|
end
|
56
58
|
|
@@ -107,7 +109,7 @@ class Diff::LCS::DiffCallbacks
|
|
107
109
|
# Returns the difference set collected during the diff process.
|
108
110
|
attr_reader :diffs
|
109
111
|
|
110
|
-
def initialize # :yields self
|
112
|
+
def initialize # :yields: self
|
111
113
|
@hunk = []
|
112
114
|
@diffs = []
|
113
115
|
|
@@ -131,11 +133,11 @@ class Diff::LCS::DiffCallbacks
|
|
131
133
|
end
|
132
134
|
|
133
135
|
def discard_a(event)
|
134
|
-
@hunk << Diff::LCS::Change.new(
|
136
|
+
@hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element)
|
135
137
|
end
|
136
138
|
|
137
139
|
def discard_b(event)
|
138
|
-
@hunk << Diff::LCS::Change.new(
|
140
|
+
@hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element)
|
139
141
|
end
|
140
142
|
|
141
143
|
def finish_hunk
|
@@ -302,7 +304,7 @@ class Diff::LCS::SDiffCallbacks
|
|
302
304
|
# Returns the difference set collected during the diff process.
|
303
305
|
attr_reader :diffs
|
304
306
|
|
305
|
-
def initialize
|
307
|
+
def initialize # :yields: self
|
306
308
|
@diffs = []
|
307
309
|
yield self if block_given?
|
308
310
|
end
|
data/lib/diff/lcs/change.rb
CHANGED
@@ -4,13 +4,13 @@
|
|
4
4
|
# addition of an element from either the old or the new sequenced
|
5
5
|
# enumerable.
|
6
6
|
class Diff::LCS::Change
|
7
|
-
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 #
|
7
|
+
IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName
|
8
8
|
|
9
9
|
# The only actions valid for changes are '+' (add), '-' (delete), '='
|
10
10
|
# (no change), '!' (changed), '<' (tail changes from first sequence), or
|
11
11
|
# '>' (tail changes from second sequence). The last two ('<>') are only
|
12
12
|
# found with Diff::LCS::diff and Diff::LCS::sdiff.
|
13
|
-
VALID_ACTIONS = %w
|
13
|
+
VALID_ACTIONS = %w[+ - = ! > <].freeze
|
14
14
|
|
15
15
|
def self.valid_action?(action)
|
16
16
|
VALID_ACTIONS.include? action
|
@@ -28,7 +28,7 @@ class Diff::LCS::Change
|
|
28
28
|
@action, @position, @element = *args
|
29
29
|
|
30
30
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
31
|
-
fail
|
31
|
+
fail "Invalid Position Type" unless @position.is_a? IntClass
|
32
32
|
end
|
33
33
|
|
34
34
|
def inspect(*_args)
|
@@ -39,7 +39,7 @@ class Diff::LCS::Change
|
|
39
39
|
[@action, @position, @element]
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
alias_method :to_ary, :to_a
|
43
43
|
|
44
44
|
def self.from_a(arr)
|
45
45
|
arr = arr.flatten(1)
|
@@ -49,7 +49,7 @@ class Diff::LCS::Change
|
|
49
49
|
when 3
|
50
50
|
Diff::LCS::Change.new(*(arr[0...3]))
|
51
51
|
else
|
52
|
-
fail
|
52
|
+
fail "Invalid change array format provided."
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -70,27 +70,27 @@ class Diff::LCS::Change
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def adding?
|
73
|
-
@action ==
|
73
|
+
@action == "+"
|
74
74
|
end
|
75
75
|
|
76
76
|
def deleting?
|
77
|
-
@action ==
|
77
|
+
@action == "-"
|
78
78
|
end
|
79
79
|
|
80
80
|
def unchanged?
|
81
|
-
@action ==
|
81
|
+
@action == "="
|
82
82
|
end
|
83
83
|
|
84
84
|
def changed?
|
85
|
-
@action ==
|
85
|
+
@action == "!"
|
86
86
|
end
|
87
87
|
|
88
88
|
def finished_a?
|
89
|
-
@action ==
|
89
|
+
@action == ">"
|
90
90
|
end
|
91
91
|
|
92
92
|
def finished_b?
|
93
|
-
@action ==
|
93
|
+
@action == "<"
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
@@ -115,8 +115,8 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
115
115
|
@action, @old_position, @old_element, @new_position, @new_element = *args
|
116
116
|
|
117
117
|
fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
|
118
|
-
fail
|
119
|
-
fail
|
118
|
+
fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass)
|
119
|
+
fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass)
|
120
120
|
end
|
121
121
|
|
122
122
|
def to_a
|
@@ -127,7 +127,7 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
127
127
|
]
|
128
128
|
end
|
129
129
|
|
130
|
-
|
130
|
+
alias_method :to_ary, :to_a
|
131
131
|
|
132
132
|
def self.from_a(arr)
|
133
133
|
Diff::LCS::Change.from_a(arr)
|
@@ -139,15 +139,15 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
|
|
139
139
|
ea = event.to_a
|
140
140
|
|
141
141
|
case ea[0]
|
142
|
-
when
|
142
|
+
when "-"
|
143
143
|
ea[2][1] = nil
|
144
|
-
when
|
145
|
-
ea[0] =
|
144
|
+
when "<"
|
145
|
+
ea[0] = "-"
|
146
146
|
ea[2][1] = nil
|
147
|
-
when
|
147
|
+
when "+"
|
148
148
|
ea[1][1] = nil
|
149
|
-
when
|
150
|
-
ea[0] =
|
149
|
+
when ">"
|
150
|
+
ea[0] = "+"
|
151
151
|
ea[1][1] = nil
|
152
152
|
end
|
153
153
|
|
data/lib/diff/lcs/htmldiff.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "cgi"
|
4
4
|
|
5
5
|
# Produce a simple HTML diff view.
|
6
6
|
class Diff::LCS::HTMLDiff
|
7
7
|
class << self
|
8
|
-
|
8
|
+
# standard:disable ThreadSafety/ClassAndModuleAttributes
|
9
|
+
attr_accessor :can_expand_tabs # :nodoc:
|
10
|
+
# standard:enable ThreadSafety/ClassAndModuleAttributes
|
9
11
|
end
|
10
12
|
self.can_expand_tabs = true
|
11
13
|
|
12
|
-
class Callbacks
|
14
|
+
class Callbacks # :nodoc:
|
13
15
|
attr_accessor :output
|
14
16
|
attr_accessor :match_class
|
15
17
|
attr_accessor :only_a_class
|
@@ -19,14 +21,14 @@ class Diff::LCS::HTMLDiff
|
|
19
21
|
@output = output
|
20
22
|
options ||= {}
|
21
23
|
|
22
|
-
@match_class = options[:match_class] ||
|
23
|
-
@only_a_class = options[:only_a_class] ||
|
24
|
-
@only_b_class = options[:only_b_class] ||
|
24
|
+
@match_class = options[:match_class] || "match"
|
25
|
+
@only_a_class = options[:only_a_class] || "only_a"
|
26
|
+
@only_b_class = options[:only_b_class] || "only_b"
|
25
27
|
end
|
26
28
|
|
27
29
|
def htmlize(element, css_class)
|
28
|
-
element =
|
29
|
-
%
|
30
|
+
element = " " if element.empty?
|
31
|
+
%(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
|
30
32
|
end
|
31
33
|
private :htmlize
|
32
34
|
|
@@ -46,13 +48,16 @@ class Diff::LCS::HTMLDiff
|
|
46
48
|
end
|
47
49
|
end
|
48
50
|
|
51
|
+
# standard:disable Style/HashSyntax
|
49
52
|
DEFAULT_OPTIONS = {
|
50
53
|
:expand_tabs => nil,
|
51
54
|
:output => nil,
|
52
55
|
:css => nil,
|
53
56
|
:title => nil
|
54
57
|
}.freeze
|
58
|
+
# standard:enable Style/HashSyntax
|
55
59
|
|
60
|
+
# standard:disable Layout/HeredocIndentation
|
56
61
|
DEFAULT_CSS = <<-CSS
|
57
62
|
body { margin: 0; }
|
58
63
|
.diff
|
@@ -86,11 +91,12 @@ pre
|
|
86
91
|
}
|
87
92
|
h1 { margin-left: 2em; }
|
88
93
|
CSS
|
94
|
+
# standard:enable Layout/HeredocIndentation
|
89
95
|
|
90
96
|
def initialize(left, right, options = nil)
|
91
|
-
@left
|
92
|
-
@right
|
93
|
-
@options
|
97
|
+
@left = left
|
98
|
+
@right = right
|
99
|
+
@options = options
|
94
100
|
|
95
101
|
@options = DEFAULT_OPTIONS.dup if @options.nil?
|
96
102
|
end
|
@@ -103,7 +109,7 @@ h1 { margin-left: 2em; }
|
|
103
109
|
|
104
110
|
@options[:css] ||= DEFAULT_CSS.dup
|
105
111
|
|
106
|
-
@options[:title] ||=
|
112
|
+
@options[:title] ||= "diff"
|
107
113
|
end
|
108
114
|
private :verify_options
|
109
115
|
|
@@ -116,13 +122,14 @@ h1 { margin-left: 2em; }
|
|
116
122
|
formatter = Text::Format.new
|
117
123
|
formatter.tabstop = @options[:expand_tabs]
|
118
124
|
|
119
|
-
@left.map!
|
120
|
-
@right.map!
|
125
|
+
@left.map! { |line| formatter.expand(line.chomp) }
|
126
|
+
@right.map! { |line| formatter.expand(line.chomp) }
|
121
127
|
end
|
122
128
|
|
123
|
-
@left.map!
|
124
|
-
@right.map!
|
129
|
+
@left.map! { |line| CGI.escapeHTML(line.chomp) }
|
130
|
+
@right.map! { |line| CGI.escapeHTML(line.chomp) }
|
125
131
|
|
132
|
+
# standard:disable Layout/HeredocIndentation
|
126
133
|
@options[:output] << <<-OUTPUT
|
127
134
|
<html>
|
128
135
|
<head>
|
@@ -137,14 +144,17 @@ h1 { margin-left: 2em; }
|
|
137
144
|
<span class="only_b">Only in New</span></p>
|
138
145
|
<div class="diff">
|
139
146
|
OUTPUT
|
147
|
+
# standard:enable Layout/HeredocIndentation
|
140
148
|
|
141
149
|
callbacks = Callbacks.new(@options[:output])
|
142
150
|
Diff::LCS.traverse_sequences(@left, @right, callbacks)
|
143
151
|
|
152
|
+
# standard:disable Layout/HeredocIndentation
|
144
153
|
@options[:output] << <<-OUTPUT
|
145
154
|
</div>
|
146
155
|
</body>
|
147
156
|
</html>
|
148
157
|
OUTPUT
|
158
|
+
# standard:enable Layout/HeredocIndentation
|
149
159
|
end
|
150
160
|
end
|
data/lib/diff/lcs/hunk.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "diff/lcs/block"
|
4
4
|
|
5
5
|
# A Hunk is a group of Blocks which overlap because of the context surrounding
|
6
6
|
# each block. (So if we're not using context, every hunk will contain one
|
7
7
|
# block.) Used in the diff program (bin/ldiff).
|
8
8
|
class Diff::LCS::Hunk
|
9
|
-
OLD_DIFF_OP_ACTION = {
|
10
|
-
ED_DIFF_OP_ACTION = {
|
9
|
+
OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
10
|
+
ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
11
11
|
|
12
12
|
private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant)
|
13
13
|
|
@@ -22,18 +22,19 @@ class Diff::LCS::Hunk
|
|
22
22
|
end
|
23
23
|
|
24
24
|
if String.method_defined?(:encoding)
|
25
|
-
@preferred_data_encoding = data_old.fetch(0
|
25
|
+
@preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding
|
26
26
|
end
|
27
27
|
|
28
28
|
@data_old = data_old
|
29
29
|
@data_new = data_new
|
30
|
+
@old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?)
|
31
|
+
@new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?)
|
30
32
|
|
31
33
|
before = after = file_length_difference
|
32
34
|
after += @blocks[0].diff_size
|
33
35
|
@file_length_difference = after # The caller must get this manually
|
34
36
|
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
35
37
|
|
36
|
-
|
37
38
|
# Save the start & end of each array. If the array doesn't exist (e.g.,
|
38
39
|
# we're only adding items in this block), then figure out the line number
|
39
40
|
# based on the line number of the other file and the current difference in
|
@@ -54,8 +55,8 @@ class Diff::LCS::Hunk
|
|
54
55
|
|
55
56
|
@start_old = a1 || (b1 - before)
|
56
57
|
@start_new = b1 || (a1 + before)
|
57
|
-
@end_old
|
58
|
-
@end_new
|
58
|
+
@end_old = a2 || (b2 - after)
|
59
|
+
@end_new = b2 || (a2 + after)
|
59
60
|
|
60
61
|
self.flag_context = flag_context
|
61
62
|
end
|
@@ -67,12 +68,12 @@ class Diff::LCS::Hunk
|
|
67
68
|
|
68
69
|
# Change the "start" and "end" fields to note that context should be added
|
69
70
|
# to this hunk.
|
70
|
-
attr_accessor :flag_context
|
71
|
+
attr_accessor :flag_context
|
71
72
|
undef :flag_context=
|
72
|
-
def flag_context=(context)
|
73
|
-
return if context.nil?
|
73
|
+
def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods
|
74
|
+
return if context.nil? || context.zero?
|
74
75
|
|
75
|
-
add_start = context > @start_old ? @start_old : context
|
76
|
+
add_start = (context > @start_old) ? @start_old : context
|
76
77
|
|
77
78
|
@start_old -= add_start
|
78
79
|
@start_new -= add_start
|
@@ -80,14 +81,12 @@ class Diff::LCS::Hunk
|
|
80
81
|
old_size = @data_old.size
|
81
82
|
|
82
83
|
add_end =
|
83
|
-
if (@end_old + context)
|
84
|
-
old_size - @end_old
|
84
|
+
if (@end_old + context) >= old_size
|
85
|
+
old_size - @end_old - 1
|
85
86
|
else
|
86
87
|
context
|
87
88
|
end
|
88
89
|
|
89
|
-
add_end = @max_diff_size if add_end >= old_size
|
90
|
-
|
91
90
|
@end_old += add_end
|
92
91
|
@end_new += add_end
|
93
92
|
end
|
@@ -102,7 +101,7 @@ class Diff::LCS::Hunk
|
|
102
101
|
@start_new = hunk.start_new
|
103
102
|
blocks.unshift(*hunk.blocks)
|
104
103
|
end
|
105
|
-
|
104
|
+
alias_method :unshift, :merge
|
106
105
|
|
107
106
|
# Determines whether there is an overlap between this hunk and the
|
108
107
|
# provided hunk. This will be true if the difference between the two hunks
|
@@ -132,34 +131,42 @@ class Diff::LCS::Hunk
|
|
132
131
|
|
133
132
|
# Note that an old diff can't have any context. Therefore, we know that
|
134
133
|
# there's only one block in the hunk.
|
135
|
-
def old_diff(
|
136
|
-
warn
|
134
|
+
def old_diff(last = false)
|
135
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
137
136
|
|
138
137
|
block = @blocks[0]
|
139
138
|
|
139
|
+
if last
|
140
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
141
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
142
|
+
end
|
143
|
+
|
140
144
|
# Calculate item number range. Old diff range is just like a context
|
141
145
|
# diff range, except the ranges are on one line with the action between
|
142
146
|
# them.
|
143
|
-
s = encode("#{context_range(:old,
|
147
|
+
s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n")
|
144
148
|
# If removing anything, just print out all the remove lines in the hunk
|
145
149
|
# which is just all the remove lines in the block.
|
146
150
|
unless block.remove.empty?
|
147
|
-
@data_old[@start_old..@end_old].each { |e| s << encode(
|
151
|
+
@data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") }
|
148
152
|
end
|
149
153
|
|
150
|
-
s << encode("
|
154
|
+
s << encode("\\n") if old_missing_newline && !new_missing_newline
|
155
|
+
s << encode("---\n") if block.op == "!"
|
151
156
|
|
152
157
|
unless block.insert.empty?
|
153
|
-
@data_new[@start_new..@end_new].each { |e| s << encode(
|
158
|
+
@data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") }
|
154
159
|
end
|
155
160
|
|
161
|
+
s << encode("\\n") if new_missing_newline && !old_missing_newline
|
162
|
+
|
156
163
|
s
|
157
164
|
end
|
158
165
|
private :old_diff
|
159
166
|
|
160
167
|
def unified_diff(last = false)
|
161
168
|
# Calculate item number range.
|
162
|
-
s = encode("@@ -#{unified_range(:old
|
169
|
+
s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n")
|
163
170
|
|
164
171
|
# Outlist starts containing the hunk of the old file. Removing an item
|
165
172
|
# just means putting a '-' in front of it. Inserting an item requires
|
@@ -172,18 +179,20 @@ class Diff::LCS::Hunk
|
|
172
179
|
# file -- don't take removed items into account.
|
173
180
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
174
181
|
|
175
|
-
|
182
|
+
# standard:disable Performance/UnfreezeString
|
183
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
184
|
+
# standard:enable Performance/UnfreezeString
|
176
185
|
|
177
186
|
last_block = blocks[-1]
|
178
187
|
|
179
188
|
if last
|
180
|
-
old_missing_newline = missing_last_newline?(@data_old)
|
181
|
-
new_missing_newline = missing_last_newline?(@data_new)
|
189
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
190
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
182
191
|
end
|
183
192
|
|
184
193
|
@blocks.each do |block|
|
185
194
|
block.remove.each do |item|
|
186
|
-
op
|
195
|
+
op = item.action.to_s # -
|
187
196
|
offset = item.position - lo + num_added
|
188
197
|
outlist[offset][0, 1] = encode(op)
|
189
198
|
num_removed += 1
|
@@ -195,7 +204,7 @@ class Diff::LCS::Hunk
|
|
195
204
|
end
|
196
205
|
|
197
206
|
block.insert.each do |item|
|
198
|
-
op
|
207
|
+
op = item.action.to_s # +
|
199
208
|
offset = item.position - @start_new + num_removed
|
200
209
|
outlist[offset, 0] = encode(op) + @data_new[item.position].chomp
|
201
210
|
num_added += 1
|
@@ -212,8 +221,8 @@ class Diff::LCS::Hunk
|
|
212
221
|
|
213
222
|
def context_diff(last = false)
|
214
223
|
s = encode("***************\n")
|
215
|
-
s << encode("*** #{context_range(:old,
|
216
|
-
r = context_range(:new,
|
224
|
+
s << encode("*** #{context_range(:old, ",")} ****\n")
|
225
|
+
r = context_range(:new, ",")
|
217
226
|
|
218
227
|
if last
|
219
228
|
old_missing_newline = missing_last_newline?(@data_old)
|
@@ -226,7 +235,9 @@ class Diff::LCS::Hunk
|
|
226
235
|
removes = @blocks.reject { |e| e.remove.empty? }
|
227
236
|
|
228
237
|
unless removes.empty?
|
229
|
-
|
238
|
+
# standard:disable Performance/UnfreezeString
|
239
|
+
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
240
|
+
# standard:enable Performance/UnfreezeString
|
230
241
|
|
231
242
|
last_block = removes[-1]
|
232
243
|
|
@@ -248,7 +259,9 @@ class Diff::LCS::Hunk
|
|
248
259
|
inserts = @blocks.reject { |e| e.insert.empty? }
|
249
260
|
|
250
261
|
unless inserts.empty?
|
251
|
-
|
262
|
+
# standard:disable Performance/UnfreezeString
|
263
|
+
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
264
|
+
# standard:enable Performance/UnfreezeString
|
252
265
|
|
253
266
|
last_block = inserts[-1]
|
254
267
|
|
@@ -268,14 +281,24 @@ class Diff::LCS::Hunk
|
|
268
281
|
end
|
269
282
|
private :context_diff
|
270
283
|
|
271
|
-
def ed_diff(format,
|
272
|
-
warn
|
284
|
+
def ed_diff(format, last)
|
285
|
+
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
286
|
+
if last
|
287
|
+
# ed script doesn't support well incomplete lines
|
288
|
+
warn "<old_file>: No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old)
|
289
|
+
warn "<new_file>: No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new)
|
290
|
+
|
291
|
+
if @blocks[0].op == "!"
|
292
|
+
return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n"
|
293
|
+
return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element
|
294
|
+
end
|
295
|
+
end
|
273
296
|
|
274
297
|
s =
|
275
298
|
if format == :reverse_ed
|
276
|
-
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old,
|
299
|
+
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n")
|
277
300
|
else
|
278
|
-
encode("#{context_range(:old,
|
301
|
+
encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
279
302
|
end
|
280
303
|
|
281
304
|
unless @blocks[0].insert.empty?
|
@@ -290,7 +313,7 @@ class Diff::LCS::Hunk
|
|
290
313
|
|
291
314
|
# Generate a range of item numbers to print. Only print 1 number if the
|
292
315
|
# range has only one item in it. Otherwise, it's 'start,end'
|
293
|
-
def context_range(mode, op
|
316
|
+
def context_range(mode, op)
|
294
317
|
case mode
|
295
318
|
when :old
|
296
319
|
s, e = (@start_old + 1), (@end_old + 1)
|
@@ -298,28 +321,26 @@ class Diff::LCS::Hunk
|
|
298
321
|
s, e = (@start_new + 1), (@end_new + 1)
|
299
322
|
end
|
300
323
|
|
301
|
-
e
|
302
|
-
e = 1 if e.zero?
|
303
|
-
|
304
|
-
s < e ? "#{s}#{op}#{e}" : e.to_s
|
324
|
+
(s < e) ? "#{s}#{op}#{e}" : e.to_s
|
305
325
|
end
|
306
326
|
private :context_range
|
307
327
|
|
308
328
|
# Generate a range of item numbers to print for unified diff. Print number
|
309
329
|
# where block starts, followed by number of lines in the block
|
310
330
|
# (don't print number of lines if it's 1)
|
311
|
-
def unified_range(mode
|
331
|
+
def unified_range(mode)
|
312
332
|
case mode
|
313
333
|
when :old
|
334
|
+
return "0,0" if @old_empty
|
314
335
|
s, e = (@start_old + 1), (@end_old + 1)
|
315
336
|
when :new
|
337
|
+
return "0,0" if @new_empty
|
316
338
|
s, e = (@start_new + 1), (@end_new + 1)
|
317
339
|
end
|
318
340
|
|
319
|
-
length = e - s +
|
341
|
+
length = e - s + 1
|
320
342
|
|
321
|
-
|
322
|
-
length <= 1 ? first.to_s : "#{first},#{length}"
|
343
|
+
(length <= 1) ? e.to_s : "#{s},#{length}"
|
323
344
|
end
|
324
345
|
private :unified_range
|
325
346
|
|