diff-lcs 1.3 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'diff/lcs'
4
4
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ unless 0.respond_to?(:positive?)
4
+ class Fixnum # rubocop:disable Lint/UnifiedInteger, Style/Documentation
5
+ def positive?
6
+ self > 0 # rubocop:disable Styel/NumericPredicate
7
+ end
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # A block is an operation removing, adding, or changing a group of items.
4
4
  # Basically, this is just a list of changes, where each change adds or
@@ -1,8 +1,8 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'diff/lcs/change'
4
4
 
5
- module Diff::LCS
5
+ module Diff::LCS # rubocop:disable Style/Documentation
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
@@ -17,14 +17,17 @@ module Diff::LCS
17
17
  def match(event)
18
18
  event
19
19
  end
20
+
20
21
  # Called when the old value is discarded in favour of the new value.
21
22
  def discard_a(event)
22
23
  event
23
24
  end
25
+
24
26
  # Called when the new value is discarded in favour of the old value.
25
27
  def discard_b(event)
26
28
  event
27
29
  end
30
+
28
31
  # Called when both the old and new values have changed.
29
32
  def change(event)
30
33
  event
@@ -108,12 +111,12 @@ class Diff::LCS::DiffCallbacks
108
111
  @hunk = []
109
112
  @diffs = []
110
113
 
111
- if block_given?
112
- begin
113
- yield self
114
- ensure
115
- self.finish
116
- end
114
+ return unless block_given?
115
+
116
+ begin
117
+ yield self
118
+ ensure
119
+ finish
117
120
  end
118
121
  end
119
122
 
@@ -123,7 +126,7 @@ class Diff::LCS::DiffCallbacks
123
126
  finish_hunk
124
127
  end
125
128
 
126
- def match(event)
129
+ def match(_event)
127
130
  finish_hunk
128
131
  end
129
132
 
@@ -190,7 +193,7 @@ end
190
193
  # Diff::LCS::SDiffCallbacks. They may be compared as:
191
194
  #
192
195
  # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
193
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
196
+ # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
194
197
  #
195
198
  # s == c # -> true
196
199
  #
@@ -241,7 +244,7 @@ end
241
244
  # will compute and display the necessary components to show two sequences
242
245
  # and their minimized differences side by side, just like the Unix utility
243
246
  # +sdiff+.
244
- #
247
+ #
245
248
  # same same
246
249
  # before | after
247
250
  # old < -
@@ -270,7 +273,7 @@ end
270
273
  # Diff::LCS::ContextDiffCallbacks. They may be compared as:
271
274
  #
272
275
  # s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" }
273
- # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten
276
+ # c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1)
274
277
  #
275
278
  # s == c # -> true
276
279
  #
@@ -1,16 +1,16 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  # Represents a simplistic (non-contextual) change. Represents the removal or
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 # rubocop: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
@@ -27,20 +27,20 @@ class Diff::LCS::Change
27
27
  def initialize(*args)
28
28
  @action, @position, @element = *args
29
29
 
30
- unless Diff::LCS::Change.valid_action?(@action)
31
- raise "Invalid Change Action '#{@action}'"
32
- end
33
- raise "Invalid Position Type" unless @position.kind_of? IntClass
30
+ fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
31
+ fail 'Invalid Position Type' unless @position.kind_of? IntClass
34
32
  end
35
33
 
36
- def inspect
37
- to_a.inspect
34
+ def inspect(*_args)
35
+ "#<#{self.class}: #{to_a.inspect}>"
38
36
  end
39
37
 
40
38
  def to_a
41
- [ @action, @position, @element ]
39
+ [@action, @position, @element]
42
40
  end
43
41
 
42
+ alias to_ary to_a
43
+
44
44
  def self.from_a(arr)
45
45
  arr = arr.flatten(1)
46
46
  case arr.size
@@ -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
- raise "Invalid change array format provided."
52
+ fail 'Invalid change array format provided.'
53
53
  end
54
54
  end
55
55
 
@@ -57,15 +57,15 @@ class Diff::LCS::Change
57
57
 
58
58
  def ==(other)
59
59
  (self.class == other.class) and
60
- (self.action == other.action) and
61
- (self.position == other.position) and
62
- (self.element == other.element)
60
+ (action == other.action) and
61
+ (position == other.position) and
62
+ (element == other.element)
63
63
  end
64
64
 
65
65
  def <=>(other)
66
- r = self.action <=> other.action
67
- r = self.position <=> other.position if r.zero?
68
- r = self.element <=> other.element if r.zero?
66
+ r = action <=> other.action
67
+ r = position <=> other.position if r.zero?
68
+ r = element <=> other.element if r.zero?
69
69
  r
70
70
  end
71
71
 
@@ -114,27 +114,20 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
114
114
  def initialize(*args)
115
115
  @action, @old_position, @old_element, @new_position, @new_element = *args
116
116
 
117
- unless Diff::LCS::Change.valid_action?(@action)
118
- raise "Invalid Change Action '#{@action}'"
119
- end
120
- unless @old_position.nil? or @old_position.kind_of? IntClass
121
- raise "Invalid (Old) Position Type"
122
- end
123
- unless @new_position.nil? or @new_position.kind_of? IntClass
124
- raise "Invalid (New) Position Type"
125
- end
117
+ fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action)
118
+ fail 'Invalid (Old) Position Type' unless @old_position.nil? or @old_position.kind_of? IntClass
119
+ fail 'Invalid (New) Position Type' unless @new_position.nil? or @new_position.kind_of? IntClass
126
120
  end
127
121
 
128
122
  def to_a
129
- [ @action,
130
- [ @old_position, @old_element ],
131
- [ @new_position, @new_element ]
123
+ [
124
+ @action,
125
+ [@old_position, @old_element],
126
+ [@new_position, @new_element]
132
127
  ]
133
128
  end
134
129
 
135
- def inspect(*args)
136
- to_a.inspect
137
- end
130
+ alias to_ary to_a
138
131
 
139
132
  def self.from_a(arr)
140
133
  Diff::LCS::Change.from_a(arr)
@@ -163,11 +156,11 @@ class Diff::LCS::ContextChange < Diff::LCS::Change
163
156
 
164
157
  def ==(other)
165
158
  (self.class == other.class) and
166
- (@action == other.action) and
167
- (@old_position == other.old_position) and
168
- (@new_position == other.new_position) and
169
- (@old_element == other.old_element) and
170
- (@new_element == other.new_element)
159
+ (@action == other.action) and
160
+ (@old_position == other.old_position) and
161
+ (@new_position == other.new_position) and
162
+ (@old_element == other.old_element) and
163
+ (@new_element == other.new_element)
171
164
  end
172
165
 
173
166
  def <=>(other)
@@ -1,14 +1,15 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'cgi'
4
4
 
5
+ # Produce a simple HTML diff view.
5
6
  class Diff::LCS::HTMLDiff
6
7
  class << self
7
8
  attr_accessor :can_expand_tabs #:nodoc:
8
9
  end
9
10
  self.can_expand_tabs = true
10
11
 
11
- class Callbacks
12
+ class Callbacks #:nodoc:
12
13
  attr_accessor :output
13
14
  attr_accessor :match_class
14
15
  attr_accessor :only_a_class
@@ -18,14 +19,14 @@ class Diff::LCS::HTMLDiff
18
19
  @output = output
19
20
  options ||= {}
20
21
 
21
- @match_class = options[:match_class] || "match"
22
- @only_a_class = options[:only_a_class] || "only_a"
23
- @only_b_class = options[:only_b_class] || "only_b"
22
+ @match_class = options[:match_class] || 'match'
23
+ @only_a_class = options[:only_a_class] || 'only_a'
24
+ @only_b_class = options[:only_b_class] || 'only_b'
24
25
  end
25
26
 
26
27
  def htmlize(element, css_class)
27
- element = "&nbsp;" if element.empty?
28
- %Q|<pre class="#{__send__(css_class)}">#{element}</pre>\n|
28
+ element = '&nbsp;' if element.empty?
29
+ %Q(<pre class="#{__send__(css_class)}">#{element}</pre>\n)
29
30
  end
30
31
  private :htmlize
31
32
 
@@ -49,8 +50,8 @@ class Diff::LCS::HTMLDiff
49
50
  :expand_tabs => nil,
50
51
  :output => nil,
51
52
  :css => nil,
52
- :title => nil,
53
- }
53
+ :title => nil
54
+ }.freeze
54
55
 
55
56
  DEFAULT_CSS = <<-CSS
56
57
  body { margin: 0; }
@@ -96,13 +97,13 @@ h1 { margin-left: 2em; }
96
97
 
97
98
  def verify_options
98
99
  @options[:expand_tabs] ||= 4
99
- @options[:expand_tabs] = 4 if @options[:expand_tabs] < 0
100
+ @options[:expand_tabs] = 4 if @options[:expand_tabs].negative?
100
101
 
101
102
  @options[:output] ||= $stdout
102
103
 
103
104
  @options[:css] ||= DEFAULT_CSS.dup
104
105
 
105
- @options[:title] ||= "diff"
106
+ @options[:title] ||= 'diff'
106
107
  end
107
108
  private :verify_options
108
109
 
@@ -111,16 +112,16 @@ h1 { margin-left: 2em; }
111
112
  def run
112
113
  verify_options
113
114
 
114
- if @options[:expand_tabs] > 0 && self.class.can_expand_tabs
115
+ if @options[:expand_tabs].positive? && self.class.can_expand_tabs
115
116
  formatter = Text::Format.new
116
117
  formatter.tabstop = @options[:expand_tabs]
117
118
 
118
- @left.map! { |line| formatter.expand(line.chomp) }
119
- @right.map! { |line| formatter.expand(line.chomp) }
119
+ @left.map! do |line| formatter.expand(line.chomp) end
120
+ @right.map! do |line| formatter.expand(line.chomp) end
120
121
  end
121
122
 
122
- @left.map! { |line| CGI.escapeHTML(line.chomp) }
123
- @right.map! { |line| CGI.escapeHTML(line.chomp) }
123
+ @left.map! do |line| CGI.escapeHTML(line.chomp) end
124
+ @right.map! do |line| CGI.escapeHTML(line.chomp) end
124
125
 
125
126
  @options[:output] << <<-OUTPUT
126
127
  <html>
@@ -1,4 +1,4 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'diff/lcs/block'
4
4
 
@@ -10,9 +10,9 @@ class Diff::LCS::Hunk
10
10
  # the piece of data.
11
11
  def initialize(data_old, data_new, piece, flag_context, file_length_difference)
12
12
  # At first, a hunk will have just one Block in it
13
- @blocks = [ Diff::LCS::Block.new(piece) ]
13
+ @blocks = [Diff::LCS::Block.new(piece)]
14
14
  if String.method_defined?(:encoding)
15
- @preferred_data_encoding = data_old.fetch(0, data_new.fetch(0,'') ).encoding
15
+ @preferred_data_encoding = data_old.fetch(0, data_new.fetch(0, '')).encoding
16
16
  end
17
17
  @data_old = data_old
18
18
  @data_new = data_new
@@ -20,6 +20,7 @@ class Diff::LCS::Hunk
20
20
  before = after = file_length_difference
21
21
  after += @blocks[0].diff_size
22
22
  @file_length_difference = after # The caller must get this manually
23
+ @max_diff_size = @blocks.lazy.map { |e| e.diff_size }.max
23
24
 
24
25
  # Save the start & end of each array. If the array doesn't exist (e.g.,
25
26
  # we're only adding items in this block), then figure out the line
@@ -55,19 +56,23 @@ class Diff::LCS::Hunk
55
56
  # Change the "start" and "end" fields to note that context should be added
56
57
  # to this hunk.
57
58
  attr_accessor :flag_context
58
- undef :flag_context=;
59
- def flag_context=(context) #:nodoc:
59
+ undef :flag_context=
60
+ def flag_context=(context) #:nodoc: # rubocop:disable Lint/DuplicateMethods
60
61
  return if context.nil? or context.zero?
61
62
 
62
- add_start = (context > @start_old) ? @start_old : context
63
+ add_start = context > @start_old ? @start_old : context
63
64
  @start_old -= add_start
64
65
  @start_new -= add_start
65
66
 
66
- if (@end_old + context) > @data_old.size
67
- add_end = @data_old.size - @end_old
68
- else
69
- add_end = context
70
- end
67
+ add_end =
68
+ if (@end_old + context) > @data_old.size
69
+ @data_old.size - @end_old
70
+ else
71
+ context
72
+ end
73
+
74
+ add_end = @max_diff_size if add_end > @max_diff_size
75
+
71
76
  @end_old += add_end
72
77
  @end_new += add_end
73
78
  end
@@ -76,15 +81,13 @@ class Diff::LCS::Hunk
76
81
  # a truthy value so that if there is no overlap, you can know the merge
77
82
  # was skipped.
78
83
  def merge(hunk)
79
- if overlaps?(hunk)
80
- @start_old = hunk.start_old
81
- @start_new = hunk.start_new
82
- blocks.unshift(*hunk.blocks)
83
- else
84
- nil
85
- end
84
+ return unless overlaps?(hunk)
85
+
86
+ @start_old = hunk.start_old
87
+ @start_new = hunk.start_new
88
+ blocks.unshift(*hunk.blocks)
86
89
  end
87
- alias_method :unshift, :merge
90
+ alias unshift merge
88
91
 
89
92
  # Determines whether there is an overlap between this hunk and the
90
93
  # provided hunk. This will be true if the difference between the two hunks
@@ -108,15 +111,15 @@ class Diff::LCS::Hunk
108
111
  when :reverse_ed, :ed_finish
109
112
  ed_diff(format)
110
113
  else
111
- raise "Unknown diff format #{format}."
114
+ fail "Unknown diff format #{format}."
112
115
  end
113
116
  end
114
117
 
115
118
  # Note that an old diff can't have any context. Therefore, we know that
116
119
  # there's only one block in the hunk.
117
120
  def old_diff
118
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
119
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
121
+ warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
122
+ op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
120
123
 
121
124
  block = @blocks[0]
122
125
 
@@ -126,9 +129,16 @@ class Diff::LCS::Hunk
126
129
  s = encode("#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n")
127
130
  # If removing anything, just print out all the remove lines in the hunk
128
131
  # which is just all the remove lines in the block.
129
- @data_old[@start_old .. @end_old].each { |e| s << encode("< ") + e + encode("\n") } unless block.remove.empty?
130
- s << encode("---\n") if block.op == "!"
131
- @data_new[@start_new .. @end_new].each { |e| s << encode("> ") + e + encode("\n") } unless block.insert.empty?
132
+ unless block.remove.empty?
133
+ @data_old[@start_old..@end_old].each { |e| s << encode('< ') + e + encode("\n") }
134
+ end
135
+
136
+ s << encode("---\n") if block.op == '!'
137
+
138
+ unless block.insert.empty?
139
+ @data_new[@start_new..@end_new].each { |e| s << encode('> ') + e + encode("\n") }
140
+ end
141
+
132
142
  s
133
143
  end
134
144
  private :old_diff
@@ -148,7 +158,7 @@ class Diff::LCS::Hunk
148
158
  # file -- don't take removed items into account.
149
159
  lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
150
160
 
151
- outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
161
+ outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
152
162
 
153
163
  @blocks.each do |block|
154
164
  block.remove.each do |item|
@@ -177,13 +187,13 @@ class Diff::LCS::Hunk
177
187
  # Print out file 1 part for each block in context diff format if there
178
188
  # are any blocks that remove items
179
189
  lo, hi = @start_old, @end_old
180
- removes = @blocks.select { |e| not e.remove.empty? }
190
+ removes = @blocks.reject { |e| e.remove.empty? }
181
191
  if removes
182
- outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
192
+ outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
183
193
 
184
194
  removes.each do |block|
185
195
  block.remove.each do |item|
186
- outlist[item.position - lo][0, 1] = encode(block.op) # - or !
196
+ outlist[item.position - lo].insert(0, encode(block.op)) # - or !
187
197
  end
188
198
  end
189
199
  s << outlist.join("\n")
@@ -191,12 +201,12 @@ class Diff::LCS::Hunk
191
201
 
192
202
  s << encode("\n--- #{r} ----\n")
193
203
  lo, hi = @start_new, @end_new
194
- inserts = @blocks.select { |e| not e.insert.empty? }
204
+ inserts = @blocks.reject { |e| e.insert.empty? }
195
205
  if inserts
196
- outlist = @data_new[lo .. hi].collect { |e| e.insert(0, encode(' ')) }
206
+ outlist = @data_new[lo..hi].collect { |e| e.insert(0, encode(' ')) }
197
207
  inserts.each do |block|
198
208
  block.insert.each do |item|
199
- outlist[item.position - lo][0, 1] = encode(block.op) # + or !
209
+ outlist[item.position - lo].insert(0, encode(block.op)) # - or !
200
210
  end
201
211
  end
202
212
  s << outlist.join("\n")
@@ -206,17 +216,18 @@ class Diff::LCS::Hunk
206
216
  private :context_diff
207
217
 
208
218
  def ed_diff(format)
209
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
210
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
211
-
212
- if format == :reverse_ed
213
- s = encode("#{op_act[@blocks[0].op]}#{context_range(:old)}\n")
214
- else
215
- s = encode("#{context_range(:old, ' ')}#{op_act[@blocks[0].op]}\n")
216
- end
219
+ op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
220
+ warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
221
+
222
+ s =
223
+ if format == :reverse_ed
224
+ encode("#{op_act[@blocks[0].op]}#{context_range(:old)}\n")
225
+ else
226
+ encode("#{context_range(:old, ' ')}#{op_act[@blocks[0].op]}\n")
227
+ end
217
228
 
218
229
  unless @blocks[0].insert.empty?
219
- @data_new[@start_new .. @end_new].each { |e| s << e + encode("\n") }
230
+ @data_new[@start_new..@end_new].each do |e| s << e + encode("\n") end
220
231
  s << encode(".\n")
221
232
  end
222
233
  s
@@ -225,7 +236,7 @@ class Diff::LCS::Hunk
225
236
 
226
237
  # Generate a range of item numbers to print. Only print 1 number if the
227
238
  # range has only one item in it. Otherwise, it's 'start,end'
228
- def context_range(mode, op = ',')
239
+ def context_range(mode, op = ',') # rubocop:disable Naming/UncommunicativeMethodParamName
229
240
  case mode
230
241
  when :old
231
242
  s, e = (@start_old + 1), (@end_old + 1)
@@ -233,7 +244,7 @@ class Diff::LCS::Hunk
233
244
  s, e = (@start_new + 1), (@end_new + 1)
234
245
  end
235
246
 
236
- (s < e) ? "#{s}#{op}#{e}" : "#{e}"
247
+ s < e ? "#{s}#{op}#{e}" : e.to_s
237
248
  end
238
249
  private :context_range
239
250
 
@@ -249,8 +260,8 @@ class Diff::LCS::Hunk
249
260
  end
250
261
 
251
262
  length = e - s + 1
252
- first = (length < 2) ? e : s # "strange, but correct"
253
- (length == 1) ? "#{first}" : "#{first},#{length}"
263
+ first = length < 2 ? e : s # "strange, but correct"
264
+ length == 1 ? first.to_s : "#{first},#{length}"
254
265
  end
255
266
  private :unified_range
256
267
 
@@ -263,10 +274,11 @@ class Diff::LCS::Hunk
263
274
  args.map { |arg| arg.encode(string.encoding) }
264
275
  end
265
276
  else
266
- def encode(literal, target_encoding = nil)
277
+ def encode(literal, _target_encoding = nil)
267
278
  literal
268
279
  end
269
- def encode_as(string, *args)
280
+
281
+ def encode_as(_string, *args)
270
282
  args
271
283
  end
272
284
  end