diff-lcs 1.5.1 → 2.0.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 +581 -0
- data/CODE_OF_CONDUCT.md +166 -0
- data/CONTRIBUTING.md +127 -0
- data/CONTRIBUTORS.md +59 -0
- data/LICENCE.md +68 -0
- data/Manifest.txt +99 -35
- data/README.md +105 -0
- data/Rakefile +107 -96
- data/SECURITY.md +36 -0
- data/integration/compare/array_diff_spec.rb +10 -0
- data/integration/compare/hash_diff_spec.rb +25 -0
- data/integration/compare/string_diff_spec.rb +10 -0
- data/integration/rspec_differ_spec.rb +26 -0
- data/integration/rspec_expectations_spec.rb +32 -0
- data/integration/runner +20 -0
- data/lib/diff/lcs/block.rb +29 -24
- data/lib/diff/lcs/callbacks.rb +240 -242
- data/lib/diff/lcs/change.rb +102 -104
- data/lib/diff/lcs/hunk.rb +110 -157
- data/lib/diff/lcs/internals.rb +92 -96
- data/lib/diff/lcs/ldiff.rb +81 -73
- data/lib/diff/lcs/version.rb +7 -0
- data/lib/diff/lcs.rb +440 -466
- data/{docs → licenses}/artistic.txt +1 -1
- data/licenses/dco.txt +34 -0
- data/spec/hunk_spec.rb +33 -46
- data/spec/issues_spec.rb +32 -32
- data/spec/lcs_spec.rb +6 -6
- data/spec/ldiff_spec.rb +27 -16
- data/spec/patch_spec.rb +1 -1
- data/spec/spec_helper.rb +98 -108
- data/test/fixtures/123_x +2 -0
- data/test/fixtures/456_x +2 -0
- data/test/fixtures/empty +0 -0
- data/test/fixtures/file1.bin +0 -0
- data/test/fixtures/file2.bin +0 -0
- data/test/fixtures/four_lines +4 -0
- data/test/fixtures/four_lines_with_missing_new_line +4 -0
- data/test/fixtures/ldiff/diff.missing_new_line1-e +1 -0
- data/test/fixtures/ldiff/diff.missing_new_line1-f +1 -0
- data/test/fixtures/ldiff/diff.missing_new_line2-e +1 -0
- data/test/fixtures/ldiff/diff.missing_new_line2-f +1 -0
- data/test/fixtures/ldiff/error.diff.chef-e +2 -0
- data/test/fixtures/ldiff/error.diff.chef-f +2 -0
- data/test/fixtures/ldiff/error.diff.missing_new_line1-e +1 -0
- data/test/fixtures/ldiff/error.diff.missing_new_line1-f +1 -0
- data/test/fixtures/ldiff/error.diff.missing_new_line2-e +1 -0
- data/test/fixtures/ldiff/error.diff.missing_new_line2-f +1 -0
- data/test/fixtures/ldiff/output.diff-c +7 -0
- data/test/fixtures/ldiff/output.diff-u +5 -0
- data/test/fixtures/ldiff/output.diff.bin1 +0 -0
- data/test/fixtures/ldiff/output.diff.bin1-c +0 -0
- data/test/fixtures/ldiff/output.diff.bin1-e +0 -0
- data/test/fixtures/ldiff/output.diff.bin1-f +0 -0
- data/test/fixtures/ldiff/output.diff.bin1-u +0 -0
- data/test/fixtures/ldiff/output.diff.bin2 +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-c +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-e +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-f +1 -0
- data/test/fixtures/ldiff/output.diff.bin2-u +1 -0
- data/{spec → test}/fixtures/ldiff/output.diff.chef-c +2 -2
- data/test/fixtures/ldiff/output.diff.chef-u +9 -0
- data/{spec → test}/fixtures/ldiff/output.diff.chef2-c +2 -2
- data/{spec → test}/fixtures/ldiff/output.diff.chef2-u +2 -2
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines +5 -0
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-c +9 -0
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-e +6 -0
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-f +6 -0
- data/test/fixtures/ldiff/output.diff.empty.vs.four_lines-u +7 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty +5 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-c +9 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-e +1 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-f +1 -0
- data/test/fixtures/ldiff/output.diff.four_lines.vs.empty-u +7 -0
- data/test/fixtures/ldiff/output.diff.issue95_trailing_context +4 -0
- data/test/fixtures/ldiff/output.diff.issue95_trailing_context-c +9 -0
- data/{spec/fixtures/ldiff/output.diff-e → test/fixtures/ldiff/output.diff.issue95_trailing_context-e} +1 -1
- data/{spec/fixtures/ldiff/output.diff-f → test/fixtures/ldiff/output.diff.issue95_trailing_context-f} +1 -1
- data/test/fixtures/ldiff/output.diff.issue95_trailing_context-u +6 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line1 +5 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line1-c +14 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line1-e +0 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line1-f +0 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line1-u +9 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line2 +5 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line2-c +14 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line2-e +0 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line2-f +0 -0
- data/test/fixtures/ldiff/output.diff.missing_new_line2-u +9 -0
- data/test/test_block.rb +34 -0
- data/test/test_change.rb +234 -0
- data/test/test_diff.rb +53 -0
- data/test/test_helper.rb +225 -0
- data/test/test_hunk.rb +72 -0
- data/test/test_issues.rb +168 -0
- data/test/test_lcs.rb +47 -0
- data/test/test_ldiff.rb +89 -0
- data/test/test_patch.rb +362 -0
- data/test/test_sdiff.rb +167 -0
- data/test/test_traverse_balanced.rb +322 -0
- data/test/test_traverse_sequences.rb +187 -0
- metadata +211 -103
- data/.rspec +0 -1
- data/Code-of-Conduct.md +0 -74
- data/Contributing.md +0 -121
- data/History.md +0 -431
- data/License.md +0 -41
- data/README.rdoc +0 -84
- data/bin/htmldiff +0 -35
- data/lib/diff/lcs/backports.rb +0 -9
- data/lib/diff/lcs/htmldiff.rb +0 -158
- data/spec/fixtures/ldiff/output.diff-c +0 -7
- data/spec/fixtures/ldiff/output.diff-u +0 -5
- data/spec/fixtures/ldiff/output.diff.chef-e +0 -3
- data/spec/fixtures/ldiff/output.diff.chef-f +0 -3
- data/spec/fixtures/ldiff/output.diff.chef-u +0 -9
- data/spec/fixtures/ldiff/output.diff.chef2-e +0 -7
- data/spec/fixtures/ldiff/output.diff.chef2-f +0 -7
- /data/{docs → licenses}/COPYING.txt +0 -0
- /data/{spec → test}/fixtures/aX +0 -0
- /data/{spec → test}/fixtures/bXaX +0 -0
- /data/{spec → test}/fixtures/ds1.csv +0 -0
- /data/{spec → test}/fixtures/ds2.csv +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef2 +0 -0
- /data/{spec → test}/fixtures/ldiff/output.diff.chef2-d +0 -0
- /data/{spec → test}/fixtures/new-chef +0 -0
- /data/{spec → test}/fixtures/new-chef2 +0 -0
- /data/{spec → test}/fixtures/old-chef +0 -0
- /data/{spec → test}/fixtures/old-chef2 +0 -0
data/lib/diff/lcs/hunk.rb
CHANGED
|
@@ -2,41 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
require "diff/lcs/block"
|
|
4
4
|
|
|
5
|
-
# A Hunk is a group of Blocks which overlap because of the context surrounding
|
|
6
|
-
#
|
|
7
|
-
#
|
|
5
|
+
# A Hunk is a group of Blocks which overlap because of the context surrounding each block.
|
|
6
|
+
# (So if we're not using context, every hunk will contain one block.) Used in the diff
|
|
7
|
+
# program (bin/ldiff).
|
|
8
8
|
class Diff::LCS::Hunk
|
|
9
9
|
OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc:
|
|
10
|
-
|
|
10
|
+
private_constant :OLD_DIFF_OP_ACTION
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Create a hunk using references to both the old and new data, as well as the
|
|
15
|
-
# piece of data.
|
|
12
|
+
# Create a hunk using references to both the old and new data, as well as the piece of
|
|
13
|
+
# data.
|
|
16
14
|
def initialize(data_old, data_new, piece, flag_context, file_length_difference)
|
|
17
15
|
# At first, a hunk will have just one Block in it
|
|
18
|
-
@blocks = [Diff::LCS::Block.
|
|
16
|
+
@blocks = [Diff::LCS::Block.from_chunk(piece)]
|
|
19
17
|
|
|
20
18
|
if @blocks[0].remove.empty? && @blocks[0].insert.empty?
|
|
21
19
|
fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions"
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
@preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding
|
|
23
|
+
@newline = "\n".encode(@preferred_data_encoding)
|
|
24
|
+
@missing_newline = "\".encode(@preferred_data_encoding)
|
|
27
25
|
|
|
28
26
|
@data_old = data_old
|
|
29
27
|
@data_new = data_new
|
|
28
|
+
@old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?)
|
|
29
|
+
@new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?)
|
|
30
30
|
|
|
31
31
|
before = after = file_length_difference
|
|
32
32
|
after += @blocks[0].diff_size
|
|
33
33
|
@file_length_difference = after # The caller must get this manually
|
|
34
34
|
@max_diff_size = @blocks.map { |e| e.diff_size.abs }.max
|
|
35
35
|
|
|
36
|
-
# Save the start
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# file lengths.
|
|
36
|
+
# Save the start and end of each array. If the array doesn't exist (e.g., we're only
|
|
37
|
+
# adding items in this block), then figure out the line number based on the line
|
|
38
|
+
# number of the other file and the current difference in file lengths.
|
|
40
39
|
if @blocks[0].remove.empty?
|
|
41
40
|
a1 = a2 = nil
|
|
42
41
|
else
|
|
@@ -64,11 +63,13 @@ class Diff::LCS::Hunk
|
|
|
64
63
|
attr_reader :end_old, :end_new
|
|
65
64
|
attr_reader :file_length_difference
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
# to this hunk.
|
|
69
|
-
attr_accessor :flag_context
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
##
|
|
67
|
+
# Change the "start" and "end" fields to note that context should be added to this hunk.
|
|
68
|
+
# :attr_accessor: :flag_context
|
|
69
|
+
attr_reader :flag_context
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
def flag_context=(context) # :nodoc:
|
|
72
73
|
return if context.nil? || context.zero?
|
|
73
74
|
|
|
74
75
|
add_start = (context > @start_old) ? @start_old : context
|
|
@@ -79,21 +80,18 @@ class Diff::LCS::Hunk
|
|
|
79
80
|
old_size = @data_old.size
|
|
80
81
|
|
|
81
82
|
add_end =
|
|
82
|
-
if (@end_old + context)
|
|
83
|
-
old_size - @end_old
|
|
83
|
+
if (@end_old + context) >= old_size
|
|
84
|
+
old_size - @end_old - 1
|
|
84
85
|
else
|
|
85
86
|
context
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
add_end = @max_diff_size if add_end >= old_size
|
|
89
|
-
|
|
90
89
|
@end_old += add_end
|
|
91
90
|
@end_new += add_end
|
|
92
91
|
end
|
|
93
92
|
|
|
94
|
-
# Merges this hunk and the provided hunk together if they overlap. Returns
|
|
95
|
-
#
|
|
96
|
-
# was skipped.
|
|
93
|
+
# Merges this hunk and the provided hunk together if they overlap. Returns a truthy
|
|
94
|
+
# value so that if there is no overlap, you can know the merge was skipped.
|
|
97
95
|
def merge(hunk)
|
|
98
96
|
return unless overlaps?(hunk)
|
|
99
97
|
|
|
@@ -103,12 +101,11 @@ class Diff::LCS::Hunk
|
|
|
103
101
|
end
|
|
104
102
|
alias_method :unshift, :merge
|
|
105
103
|
|
|
106
|
-
# Determines whether there is an overlap between this hunk and the
|
|
107
|
-
#
|
|
108
|
-
#
|
|
104
|
+
# Determines whether there is an overlap between this hunk and the provided hunk. This
|
|
105
|
+
# will be true if the difference between the two hunks start or end positions is within
|
|
106
|
+
# one position of each other.
|
|
109
107
|
def overlaps?(hunk)
|
|
110
|
-
hunk
|
|
111
|
-
((@start_new - hunk.end_new) <= 1))
|
|
108
|
+
hunk && (((@start_old - hunk.end_old) <= 1) || ((@start_new - hunk.end_new) <= 1))
|
|
112
109
|
end
|
|
113
110
|
|
|
114
111
|
# Returns a diff string based on a format.
|
|
@@ -120,182 +117,164 @@ class Diff::LCS::Hunk
|
|
|
120
117
|
unified_diff(last)
|
|
121
118
|
when :context
|
|
122
119
|
context_diff(last)
|
|
123
|
-
when :ed
|
|
124
|
-
self
|
|
125
|
-
when :reverse_ed, :ed_finish
|
|
126
|
-
ed_diff(format, last)
|
|
127
120
|
else
|
|
128
121
|
fail "Unknown diff format #{format}."
|
|
129
122
|
end
|
|
130
123
|
end
|
|
131
124
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
# Note that an old diff can't have any context. Therefore, we know that there's only one
|
|
128
|
+
# block in the hunk.
|
|
129
|
+
def old_diff(last = false)
|
|
135
130
|
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
|
136
131
|
|
|
132
|
+
del, ins, sep, _ = ["< ", "> ", "---\n", "\\n"]
|
|
133
|
+
.map { _1.encode(@preferred_data_encoding) }
|
|
134
|
+
|
|
137
135
|
block = @blocks[0]
|
|
138
136
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
#
|
|
137
|
+
if last
|
|
138
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
|
139
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Calculate item number range. Old diff range is just like a context diff range,
|
|
143
|
+
# except the ranges are on one line with the action between them.
|
|
144
|
+
s = "#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n"
|
|
145
|
+
.encode(@preferred_data_encoding)
|
|
146
|
+
# If removing anything, just print out all the remove lines in the hunk which is just
|
|
147
|
+
# all the remove lines in the block.
|
|
145
148
|
unless block.remove.empty?
|
|
146
|
-
@data_old[@start_old..@end_old].each { |e| s <<
|
|
149
|
+
@data_old[@start_old..@end_old].each { |e| s << del + e.chomp + @newline }
|
|
147
150
|
end
|
|
148
151
|
|
|
149
|
-
s <<
|
|
152
|
+
s << @missing_newline << @newline if old_missing_newline && !new_missing_newline
|
|
153
|
+
s << sep if block.op == "!"
|
|
150
154
|
|
|
151
155
|
unless block.insert.empty?
|
|
152
|
-
@data_new[@start_new..@end_new].each { |e| s <<
|
|
156
|
+
@data_new[@start_new..@end_new].each { |e| s << ins + e.chomp + @newline }
|
|
153
157
|
end
|
|
154
158
|
|
|
159
|
+
s << @missing_newline << @newline if new_missing_newline && !old_missing_newline
|
|
160
|
+
|
|
155
161
|
s
|
|
156
162
|
end
|
|
157
|
-
private :old_diff
|
|
158
163
|
|
|
159
164
|
def unified_diff(last = false)
|
|
160
165
|
# Calculate item number range.
|
|
161
|
-
s =
|
|
166
|
+
s = "@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n"
|
|
167
|
+
.encode(@preferred_data_encoding)
|
|
162
168
|
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
# changed the length of outlist.
|
|
169
|
+
# `outlist` starts containing the hunk of the old file. Removing an item just means
|
|
170
|
+
# putting a '-' in front of it. Inserting an item requires getting it from the new
|
|
171
|
+
# file and splicing it in. We splice in `num_added` items. Remove blocks use
|
|
172
|
+
# `num_added` because splicing changed the length of outlist.
|
|
168
173
|
#
|
|
169
|
-
# We remove
|
|
170
|
-
#
|
|
171
|
-
#
|
|
174
|
+
# We remove `num_removed` items. Insert blocks use `num_removed` because their item
|
|
175
|
+
# numbers -- corresponding to positions in the NEW file -- don't take removed items
|
|
176
|
+
# into account.
|
|
172
177
|
lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
|
|
173
178
|
|
|
174
|
-
|
|
175
|
-
outlist = @data_old[lo..hi].map { |e|
|
|
176
|
-
# standard:enable Performance/UnfreezeString
|
|
179
|
+
space = " ".encode(@preferred_data_encoding)
|
|
180
|
+
outlist = @data_old[lo..hi].map { |e| "#{space}#{e.chomp}" }
|
|
177
181
|
|
|
178
182
|
last_block = blocks[-1]
|
|
179
183
|
|
|
180
184
|
if last
|
|
181
|
-
old_missing_newline = missing_last_newline?(@data_old)
|
|
182
|
-
new_missing_newline = missing_last_newline?(@data_new)
|
|
185
|
+
old_missing_newline = !@old_empty && missing_last_newline?(@data_old)
|
|
186
|
+
new_missing_newline = !@new_empty && missing_last_newline?(@data_new)
|
|
183
187
|
end
|
|
184
188
|
|
|
185
189
|
@blocks.each do |block|
|
|
186
190
|
block.remove.each do |item|
|
|
187
|
-
op = item.action.to_s # -
|
|
188
191
|
offset = item.position - lo + num_added
|
|
189
|
-
outlist[offset][0, 1] = encode(
|
|
192
|
+
outlist[offset][0, 1] = item.action.to_s.encode(@preferred_data_encoding) # -
|
|
190
193
|
num_removed += 1
|
|
191
194
|
end
|
|
192
195
|
|
|
193
196
|
if last && block == last_block && old_missing_newline && !new_missing_newline
|
|
194
|
-
outlist <<
|
|
197
|
+
outlist << @missing_newline
|
|
195
198
|
num_removed += 1
|
|
196
199
|
end
|
|
197
200
|
|
|
198
201
|
block.insert.each do |item|
|
|
199
|
-
op = item.action.to_s # +
|
|
202
|
+
op = item.action.to_s.encode(@preferred_data_encoding) # +
|
|
200
203
|
offset = item.position - @start_new + num_removed
|
|
201
|
-
outlist[offset, 0] =
|
|
204
|
+
outlist[offset, 0] = op + @data_new[item.position].chomp
|
|
202
205
|
num_added += 1
|
|
203
206
|
end
|
|
204
207
|
end
|
|
205
208
|
|
|
206
|
-
outlist <<
|
|
209
|
+
outlist << @missing_newline if last && new_missing_newline
|
|
207
210
|
|
|
208
|
-
s << outlist.join(
|
|
211
|
+
s << outlist.join("\n".encode(@preferred_data_encoding))
|
|
209
212
|
|
|
210
213
|
s
|
|
211
214
|
end
|
|
212
|
-
private :unified_diff
|
|
213
215
|
|
|
214
216
|
def context_diff(last = false)
|
|
215
|
-
s =
|
|
216
|
-
s <<
|
|
217
|
-
r = context_range(:new, ","
|
|
217
|
+
s = "***************\n".encode(@preferred_data_encoding)
|
|
218
|
+
s << "*** #{context_range(:old, ",")} ****\n".encode(@preferred_data_encoding)
|
|
219
|
+
r = context_range(:new, ",")
|
|
220
|
+
|
|
221
|
+
spaces = " ".encode(@preferred_data_encoding)
|
|
218
222
|
|
|
219
223
|
if last
|
|
220
224
|
old_missing_newline = missing_last_newline?(@data_old)
|
|
221
225
|
new_missing_newline = missing_last_newline?(@data_new)
|
|
222
226
|
end
|
|
223
227
|
|
|
224
|
-
# Print out file 1 part for each block in context diff format if there
|
|
225
|
-
#
|
|
228
|
+
# Print out file 1 part for each block in context diff format if there are any blocks
|
|
229
|
+
# that remove items
|
|
226
230
|
lo, hi = @start_old, @end_old
|
|
227
231
|
removes = @blocks.reject { |e| e.remove.empty? }
|
|
228
232
|
|
|
229
233
|
unless removes.empty?
|
|
230
|
-
#
|
|
231
|
-
outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
|
232
|
-
# standard:enable Performance/UnfreezeString
|
|
234
|
+
outlist = @data_old[lo..hi].map { |e| "#{spaces}#{e.chomp}" }
|
|
233
235
|
|
|
234
236
|
last_block = removes[-1]
|
|
235
237
|
|
|
236
238
|
removes.each do |block|
|
|
237
239
|
block.remove.each do |item|
|
|
238
|
-
outlist[item.position - lo][0, 1] =
|
|
240
|
+
outlist[item.position - lo][0, 1] = block.op.encode(@preferred_data_encoding) # - or !
|
|
239
241
|
end
|
|
240
242
|
|
|
241
243
|
if last && block == last_block && old_missing_newline
|
|
242
|
-
outlist <<
|
|
244
|
+
outlist << @missing_newline
|
|
243
245
|
end
|
|
244
246
|
end
|
|
245
247
|
|
|
246
|
-
s << outlist.join(
|
|
248
|
+
s << outlist.join(@newline) << @newline
|
|
247
249
|
end
|
|
248
250
|
|
|
249
|
-
s <<
|
|
251
|
+
s << "--- #{r} ----\n".encode(@preferred_data_encoding)
|
|
250
252
|
lo, hi = @start_new, @end_new
|
|
251
253
|
inserts = @blocks.reject { |e| e.insert.empty? }
|
|
252
254
|
|
|
253
255
|
unless inserts.empty?
|
|
254
|
-
#
|
|
255
|
-
outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") }
|
|
256
|
-
# standard:enable Performance/UnfreezeString
|
|
256
|
+
outlist = @data_new[lo..hi].map { |e| "#{spaces}#{e.chomp}" }
|
|
257
257
|
|
|
258
258
|
last_block = inserts[-1]
|
|
259
259
|
|
|
260
260
|
inserts.each do |block|
|
|
261
261
|
block.insert.each do |item|
|
|
262
|
-
outlist[item.position - lo][0, 1] =
|
|
262
|
+
outlist[item.position - lo][0, 1] = block.op.encode(@preferred_data_encoding) # + or !
|
|
263
263
|
end
|
|
264
264
|
|
|
265
265
|
if last && block == last_block && new_missing_newline
|
|
266
|
-
outlist <<
|
|
266
|
+
outlist << @missing_newline
|
|
267
267
|
end
|
|
268
268
|
end
|
|
269
|
-
s << outlist.join(
|
|
269
|
+
s << outlist.join(@newline)
|
|
270
270
|
end
|
|
271
271
|
|
|
272
272
|
s
|
|
273
273
|
end
|
|
274
|
-
private :context_diff
|
|
275
|
-
|
|
276
|
-
def ed_diff(format, _last = false)
|
|
277
|
-
warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
|
|
278
|
-
|
|
279
|
-
s =
|
|
280
|
-
if format == :reverse_ed
|
|
281
|
-
encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, ",")}\n")
|
|
282
|
-
else
|
|
283
|
-
encode("#{context_range(:old, " ")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n")
|
|
284
|
-
end
|
|
285
274
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
end
|
|
290
|
-
s << encode(".\n")
|
|
291
|
-
end
|
|
292
|
-
s
|
|
293
|
-
end
|
|
294
|
-
private :ed_diff
|
|
295
|
-
|
|
296
|
-
# Generate a range of item numbers to print. Only print 1 number if the
|
|
297
|
-
# range has only one item in it. Otherwise, it's 'start,end'
|
|
298
|
-
def context_range(mode, op, last = false)
|
|
275
|
+
# Generate a range of item numbers to print. Only print 1 number if the range has only
|
|
276
|
+
# one item in it. Otherwise, it's 'start,end'
|
|
277
|
+
def context_range(mode, op)
|
|
299
278
|
case mode
|
|
300
279
|
when :old
|
|
301
280
|
s, e = (@start_old + 1), (@end_old + 1)
|
|
@@ -303,61 +282,35 @@ class Diff::LCS::Hunk
|
|
|
303
282
|
s, e = (@start_new + 1), (@end_new + 1)
|
|
304
283
|
end
|
|
305
284
|
|
|
306
|
-
e -= 1 if last
|
|
307
|
-
e = 1 if e.zero?
|
|
308
|
-
|
|
309
285
|
(s < e) ? "#{s}#{op}#{e}" : e.to_s
|
|
310
286
|
end
|
|
311
|
-
private :context_range
|
|
312
287
|
|
|
313
|
-
# Generate a range of item numbers to print for unified diff. Print number
|
|
314
|
-
#
|
|
315
|
-
#
|
|
316
|
-
def unified_range(mode
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
288
|
+
# Generate a range of item numbers to print for unified diff. Print number where block
|
|
289
|
+
# starts, followed by number of lines in the block (don't print number of lines if it's
|
|
290
|
+
# 1)
|
|
291
|
+
def unified_range(mode)
|
|
292
|
+
s, e =
|
|
293
|
+
case mode
|
|
294
|
+
when :old
|
|
295
|
+
return "0,0" if @old_empty
|
|
296
|
+
[(@start_old + 1), (@end_old + 1)]
|
|
297
|
+
when :new
|
|
298
|
+
return "0,0" if @new_empty
|
|
299
|
+
[(@start_new + 1), (@end_new + 1)]
|
|
300
|
+
end
|
|
323
301
|
|
|
324
|
-
length = e - s +
|
|
302
|
+
length = e - s + 1
|
|
325
303
|
|
|
326
|
-
|
|
327
|
-
(length <= 1) ? first.to_s : "#{first},#{length}"
|
|
304
|
+
(length <= 1) ? e.to_s : "#{s},#{length}"
|
|
328
305
|
end
|
|
329
|
-
private :unified_range
|
|
330
306
|
|
|
331
307
|
def missing_last_newline?(data)
|
|
332
|
-
newline = encode("\n")
|
|
333
|
-
|
|
334
308
|
if data[-2]
|
|
335
|
-
data[-2].end_with?(newline) && !data[-1].end_with?(newline)
|
|
309
|
+
data[-2].end_with?(@newline) && !data[-1].end_with?(@newline)
|
|
336
310
|
elsif data[-1]
|
|
337
|
-
!data[-1].end_with?(newline)
|
|
311
|
+
!data[-1].end_with?(@newline)
|
|
338
312
|
else
|
|
339
313
|
true
|
|
340
314
|
end
|
|
341
315
|
end
|
|
342
|
-
|
|
343
|
-
if String.method_defined?(:encoding)
|
|
344
|
-
def encode(literal, target_encoding = @preferred_data_encoding)
|
|
345
|
-
literal.encode target_encoding
|
|
346
|
-
end
|
|
347
|
-
|
|
348
|
-
def encode_as(string, *args)
|
|
349
|
-
args.map { |arg| arg.encode(string.encoding) }
|
|
350
|
-
end
|
|
351
|
-
else
|
|
352
|
-
def encode(literal, _target_encoding = nil)
|
|
353
|
-
literal
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
def encode_as(_string, *args)
|
|
357
|
-
args
|
|
358
|
-
end
|
|
359
|
-
end
|
|
360
|
-
|
|
361
|
-
private :encode
|
|
362
|
-
private :encode_as
|
|
363
316
|
end
|