diff-lcs 1.3 → 1.4.2

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.
@@ -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 Style/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
@@ -19,7 +19,7 @@ class Diff::LCS::Block
19
19
  end
20
20
 
21
21
  def diff_size
22
- @insert.size - @remove.size
22
+ (@insert.size - @remove.size).abs
23
23
  end
24
24
 
25
25
  def op
@@ -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,18 +1,18 @@
1
- # -*- ruby encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'diff/lcs/block'
4
4
 
5
- # A Hunk is a group of Blocks which overlap because of the context
6
- # surrounding each block. (So if we're not using context, every hunk will
7
- # contain one block.) Used in the diff program (bin/diff).
5
+ # A Hunk is a group of Blocks which overlap because of the context surrounding
6
+ # each block. (So if we're not using context, every hunk will contain one
7
+ # block.) Used in the diff program (bin/ldiff).
8
8
  class Diff::LCS::Hunk
9
- # Create a hunk using references to both the old and new data, as well as
10
- # the piece of data.
9
+ # Create a hunk using references to both the old and new data, as well as the
10
+ # 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,26 @@ 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
64
+
63
65
  @start_old -= add_start
64
66
  @start_new -= add_start
65
67
 
66
- if (@end_old + context) > @data_old.size
67
- add_end = @data_old.size - @end_old
68
- else
69
- add_end = context
70
- end
68
+ old_size = @data_old.size
69
+
70
+ add_end =
71
+ if (@end_old + context) > old_size
72
+ old_size - @end_old
73
+ else
74
+ context
75
+ end
76
+
77
+ add_end = @max_diff_size if add_end >= old_size
78
+
71
79
  @end_old += add_end
72
80
  @end_new += add_end
73
81
  end
@@ -76,15 +84,13 @@ class Diff::LCS::Hunk
76
84
  # a truthy value so that if there is no overlap, you can know the merge
77
85
  # was skipped.
78
86
  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
87
+ return unless overlaps?(hunk)
88
+
89
+ @start_old = hunk.start_old
90
+ @start_new = hunk.start_new
91
+ blocks.unshift(*hunk.blocks)
86
92
  end
87
- alias_method :unshift, :merge
93
+ alias unshift merge
88
94
 
89
95
  # Determines whether there is an overlap between this hunk and the
90
96
  # provided hunk. This will be true if the difference between the two hunks
@@ -108,15 +114,15 @@ class Diff::LCS::Hunk
108
114
  when :reverse_ed, :ed_finish
109
115
  ed_diff(format)
110
116
  else
111
- raise "Unknown diff format #{format}."
117
+ fail "Unknown diff format #{format}."
112
118
  end
113
119
  end
114
120
 
115
121
  # Note that an old diff can't have any context. Therefore, we know that
116
122
  # there's only one block in the hunk.
117
123
  def old_diff
118
- warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1
119
- op_act = { "+" => 'a', "-" => 'd', "!" => "c" }
124
+ warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
125
+ op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
120
126
 
121
127
  block = @blocks[0]
122
128
 
@@ -126,9 +132,16 @@ class Diff::LCS::Hunk
126
132
  s = encode("#{context_range(:old)}#{op_act[block.op]}#{context_range(:new)}\n")
127
133
  # If removing anything, just print out all the remove lines in the hunk
128
134
  # 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?
135
+ unless block.remove.empty?
136
+ @data_old[@start_old..@end_old].each { |e| s << encode('< ') + e + encode("\n") }
137
+ end
138
+
139
+ s << encode("---\n") if block.op == '!'
140
+
141
+ unless block.insert.empty?
142
+ @data_new[@start_new..@end_new].each { |e| s << encode('> ') + e + encode("\n") }
143
+ end
144
+
132
145
  s
133
146
  end
134
147
  private :old_diff
@@ -148,7 +161,7 @@ class Diff::LCS::Hunk
148
161
  # file -- don't take removed items into account.
149
162
  lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0
150
163
 
151
- outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
164
+ outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
152
165
 
153
166
  @blocks.each do |block|
154
167
  block.remove.each do |item|
@@ -177,13 +190,13 @@ class Diff::LCS::Hunk
177
190
  # Print out file 1 part for each block in context diff format if there
178
191
  # are any blocks that remove items
179
192
  lo, hi = @start_old, @end_old
180
- removes = @blocks.select { |e| not e.remove.empty? }
193
+ removes = @blocks.reject { |e| e.remove.empty? }
181
194
  if removes
182
- outlist = @data_old[lo .. hi].map { |e| e.insert(0, encode(' ')) }
195
+ outlist = @data_old[lo..hi].map { |e| e.insert(0, encode(' ')) }
183
196
 
184
197
  removes.each do |block|
185
198
  block.remove.each do |item|
186
- outlist[item.position - lo][0, 1] = encode(block.op) # - or !
199
+ outlist[item.position - lo].insert(0, encode(block.op)) # - or !
187
200
  end
188
201
  end
189
202
  s << outlist.join("\n")
@@ -191,12 +204,12 @@ class Diff::LCS::Hunk
191
204
 
192
205
  s << encode("\n--- #{r} ----\n")
193
206
  lo, hi = @start_new, @end_new
194
- inserts = @blocks.select { |e| not e.insert.empty? }
207
+ inserts = @blocks.reject { |e| e.insert.empty? }
195
208
  if inserts
196
- outlist = @data_new[lo .. hi].collect { |e| e.insert(0, encode(' ')) }
209
+ outlist = @data_new[lo..hi].collect { |e| e.insert(0, encode(' ')) }
197
210
  inserts.each do |block|
198
211
  block.insert.each do |item|
199
- outlist[item.position - lo][0, 1] = encode(block.op) # + or !
212
+ outlist[item.position - lo].insert(0, encode(block.op)) # - or !
200
213
  end
201
214
  end
202
215
  s << outlist.join("\n")
@@ -206,17 +219,18 @@ class Diff::LCS::Hunk
206
219
  private :context_diff
207
220
 
208
221
  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
222
+ op_act = { '+' => 'a', '-' => 'd', '!' => 'c' }
223
+ warn 'Expecting only one block in an old diff hunk!' if @blocks.size > 1
224
+
225
+ s =
226
+ if format == :reverse_ed
227
+ encode("#{op_act[@blocks[0].op]}#{context_range(:old)}\n")
228
+ else
229
+ encode("#{context_range(:old, ' ')}#{op_act[@blocks[0].op]}\n")
230
+ end
217
231
 
218
232
  unless @blocks[0].insert.empty?
219
- @data_new[@start_new .. @end_new].each { |e| s << e + encode("\n") }
233
+ @data_new[@start_new..@end_new].each do |e| s << e + encode("\n") end
220
234
  s << encode(".\n")
221
235
  end
222
236
  s
@@ -225,7 +239,7 @@ class Diff::LCS::Hunk
225
239
 
226
240
  # Generate a range of item numbers to print. Only print 1 number if the
227
241
  # range has only one item in it. Otherwise, it's 'start,end'
228
- def context_range(mode, op = ',')
242
+ def context_range(mode, op = ',') # rubocop:disable Naming/UncommunicativeMethodParamName
229
243
  case mode
230
244
  when :old
231
245
  s, e = (@start_old + 1), (@end_old + 1)
@@ -233,7 +247,7 @@ class Diff::LCS::Hunk
233
247
  s, e = (@start_new + 1), (@end_new + 1)
234
248
  end
235
249
 
236
- (s < e) ? "#{s}#{op}#{e}" : "#{e}"
250
+ s < e ? "#{s}#{op}#{e}" : e.to_s
237
251
  end
238
252
  private :context_range
239
253
 
@@ -249,8 +263,8 @@ class Diff::LCS::Hunk
249
263
  end
250
264
 
251
265
  length = e - s + 1
252
- first = (length < 2) ? e : s # "strange, but correct"
253
- (length == 1) ? "#{first}" : "#{first},#{length}"
266
+ first = length < 2 ? e : s # "strange, but correct"
267
+ length == 1 ? first.to_s : "#{first},#{length}"
254
268
  end
255
269
  private :unified_range
256
270
 
@@ -263,10 +277,11 @@ class Diff::LCS::Hunk
263
277
  args.map { |arg| arg.encode(string.encoding) }
264
278
  end
265
279
  else
266
- def encode(literal, target_encoding = nil)
280
+ def encode(literal, _target_encoding = nil)
267
281
  literal
268
282
  end
269
- def encode_as(string, *args)
283
+
284
+ def encode_as(_string, *args)
270
285
  args
271
286
  end
272
287
  end