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.
@@ -13,7 +13,7 @@ class << Diff::LCS
13
13
 
14
14
  if block
15
15
  callbacks.diffs.map do |hunk|
16
- if hunk.kind_of? Array
16
+ if hunk.is_a? Array
17
17
  hunk.map { |hunk_block| block[hunk_block] }
18
18
  else
19
19
  block[hunk]
@@ -45,14 +45,14 @@ class << Diff::LCS::Internals
45
45
  vector = []
46
46
 
47
47
  # Collect any common elements at the beginning...
48
- while (a_start <= a_finish) and (b_start <= b_finish) and (a[a_start] == b[b_start])
48
+ while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start])
49
49
  vector[a_start] = b_start
50
50
  a_start += 1
51
51
  b_start += 1
52
52
  end
53
53
 
54
54
  # Now the end...
55
- while (a_start <= a_finish) and (b_start <= b_finish) and (a[a_finish] == b[b_finish])
55
+ while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish])
56
56
  vector[a_finish] = b_finish
57
57
  a_finish -= 1
58
58
  b_finish -= 1
@@ -63,8 +63,8 @@ class << Diff::LCS::Internals
63
63
  b_matches = position_hash(b, b_start..b_finish)
64
64
 
65
65
  thresh = []
66
- links = []
67
- string = a.kind_of?(String)
66
+ links = []
67
+ string = a.is_a?(String)
68
68
 
69
69
  (a_start..a_finish).each do |i|
70
70
  ai = string ? a[i, 1] : a[i]
@@ -75,7 +75,7 @@ class << Diff::LCS::Internals
75
75
  # it may have an optimization purpose
76
76
  # An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72
77
77
  # Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78
78
- if k and (thresh[k] > j) and (thresh[k - 1] < j)
78
+ if k && (thresh[k] > j) && (thresh[k - 1] < j)
79
79
  thresh[k] = j
80
80
  else
81
81
  k = replace_next_larger(thresh, j, k)
@@ -100,7 +100,7 @@ class << Diff::LCS::Internals
100
100
  # the object form of same) and detection of whether the patchset represents
101
101
  # changes to be made.
102
102
  def analyze_patchset(patchset, depth = 0)
103
- fail 'Patchset too complex' if depth > 1
103
+ fail "Patchset too complex" if depth > 1
104
104
 
105
105
  has_changes = false
106
106
  new_patchset = []
@@ -145,7 +145,7 @@ class << Diff::LCS::Internals
145
145
  # Diff::LCS::Change as its source, as an array will cause the creation
146
146
  # of one of the above.
147
147
  def intuit_diff_direction(src, patchset, limit = nil)
148
- string = src.kind_of?(String)
148
+ string = src.is_a?(String)
149
149
  count = left_match = left_miss = right_match = right_miss = 0
150
150
 
151
151
  patchset.each do |change|
@@ -157,22 +157,22 @@ class << Diff::LCS::Internals
157
157
  re = string ? src[change.new_position, 1] : src[change.new_position]
158
158
 
159
159
  case change.action
160
- when '-' # Remove details from the old string
160
+ when "-" # Remove details from the old string
161
161
  if le == change.old_element
162
162
  left_match += 1
163
163
  else
164
164
  left_miss += 1
165
165
  end
166
- when '+'
166
+ when "+"
167
167
  if re == change.new_element
168
168
  right_match += 1
169
169
  else
170
170
  right_miss += 1
171
171
  end
172
- when '='
172
+ when "="
173
173
  left_miss += 1 if le != change.old_element
174
174
  right_miss += 1 if re != change.new_element
175
- when '!'
175
+ when "!"
176
176
  if le == change.old_element
177
177
  left_match += 1
178
178
  elsif re == change.new_element
@@ -189,19 +189,19 @@ class << Diff::LCS::Internals
189
189
  element = string ? src[change.position, 1] : src[change.position]
190
190
 
191
191
  case change.action
192
- when '-'
192
+ when "-"
193
193
  if element == change.element
194
194
  left_match += 1
195
195
  else
196
196
  left_miss += 1
197
197
  end
198
- when '+'
198
+ when "+"
199
199
  if element == change.element
200
200
  right_match += 1
201
201
  else
202
202
  right_miss += 1
203
203
  end
204
- when '='
204
+ when "="
205
205
  if element != change.element
206
206
  left_miss += 1
207
207
  right_miss += 1
@@ -251,7 +251,7 @@ enumerable as either source or destination value."
251
251
  # This operation preserves the sort order.
252
252
  def replace_next_larger(enum, value, last_index = nil)
253
253
  # Off the end?
254
- if enum.empty? or (value > enum[-1])
254
+ if enum.empty? || (value > enum[-1])
255
255
  enum << value
256
256
  return enum.size - 1
257
257
  end
@@ -296,7 +296,7 @@ enumerable as either source or destination value."
296
296
  # positions it occupies in the Enumerable, optionally restricted to the
297
297
  # elements specified in the range of indexes specified by +interval+.
298
298
  def position_hash(enum, interval)
299
- string = enum.kind_of?(String)
299
+ string = enum.is_a?(String)
300
300
  hash = Hash.new { |h, k| h[k] = [] }
301
301
  interval.each do |i|
302
302
  k = string ? enum[i, 1] : enum[i]
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'optparse'
4
- require 'ostruct'
5
- require 'diff/lcs/hunk'
3
+ require "optparse"
4
+ require "diff/lcs/hunk"
6
5
 
7
- module Diff::LCS::Ldiff #:nodoc:
6
+ module Diff::LCS::Ldiff # :nodoc:
7
+ # standard:disable Layout/HeredocIndentation
8
8
  BANNER = <<-COPYRIGHT
9
9
  ldiff #{Diff::LCS::VERSION}
10
10
  Copyright 2004-2019 Austin Ziegler
@@ -16,60 +16,67 @@ ldiff #{Diff::LCS::VERSION}
16
16
  the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
17
17
  MIT licence.
18
18
  COPYRIGHT
19
- end
19
+ # standard:enable Layout/HeredocIndentation
20
20
 
21
- class << Diff::LCS::Ldiff
22
- attr_reader :format, :lines #:nodoc:
23
- attr_reader :file_old, :file_new #:nodoc:
24
- attr_reader :data_old, :data_new #:nodoc:
21
+ InputInfo = Struct.new(:filename, :data, :stat) do
22
+ def initialize(filename)
23
+ super(filename, ::File.read(filename), ::File.stat(filename))
24
+ end
25
+ end
26
+
27
+ class << self
28
+ attr_reader :format, :lines # :nodoc:
29
+ attr_reader :file_old, :file_new # :nodoc:
30
+ attr_reader :data_old, :data_new # :nodoc:
31
+ end
25
32
 
26
- def run(args, _input = $stdin, output = $stdout, error = $stderr) #:nodoc:
33
+ def self.run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc:
27
34
  @binary = nil
28
35
 
29
36
  args.options do |o|
30
37
  o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile"
31
- o.separator ''
38
+ o.separator ""
32
39
  o.on(
33
- '-c', '-C', '--context [LINES]', Integer,
34
- 'Displays a context diff with LINES lines', 'of context. Default 3 lines.'
40
+ "-c", "-C", "--context [LINES]", Integer,
41
+ "Displays a context diff with LINES lines", "of context. Default 3 lines."
35
42
  ) do |ctx|
36
43
  @format = :context
37
- @lines = ctx || 3
44
+ @lines = ctx || 3
38
45
  end
39
46
  o.on(
40
- '-u', '-U', '--unified [LINES]', Integer,
41
- 'Displays a unified diff with LINES lines', 'of context. Default 3 lines.'
47
+ "-u", "-U", "--unified [LINES]", Integer,
48
+ "Displays a unified diff with LINES lines", "of context. Default 3 lines."
42
49
  ) do |ctx|
43
50
  @format = :unified
44
- @lines = ctx || 3
51
+ @lines = ctx || 3
45
52
  end
46
- o.on('-e', 'Creates an \'ed\' script to change', 'oldfile to newfile.') do |_ctx|
53
+ o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx|
47
54
  @format = :ed
48
55
  end
49
- o.on('-f', 'Creates an \'ed\' script to change', 'oldfile to newfile in reverse order.') do |_ctx|
56
+ o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx|
50
57
  @format = :reverse_ed
51
58
  end
52
59
  o.on(
53
- '-a', '--text',
54
- 'Treat the files as text and compare them', 'line-by-line, even if they do not seem', 'to be text.'
60
+ "-a", "--text",
61
+ "Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text."
55
62
  ) do |_txt|
56
63
  @binary = false
57
64
  end
58
- o.on('--binary', 'Treats the files as binary.') do |_bin|
65
+ o.on("--binary", "Treats the files as binary.") do |_bin|
59
66
  @binary = true
60
67
  end
61
- o.on('-q', '--brief', 'Report only whether or not the files', 'differ, not the details.') do |_ctx|
68
+ o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx|
62
69
  @format = :report
63
70
  end
64
- o.on_tail('--help', 'Shows this text.') do
71
+ o.on_tail("--help", "Shows this text.") do
65
72
  error << o
66
73
  return 0
67
74
  end
68
- o.on_tail('--version', 'Shows the version of Diff::LCS.') do
75
+ o.on_tail("--version", "Shows the version of Diff::LCS.") do
69
76
  error << Diff::LCS::Ldiff::BANNER
70
77
  return 0
71
78
  end
72
- o.on_tail ''
79
+ o.on_tail ""
73
80
  o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.'
74
81
  o.parse!
75
82
  end
@@ -81,91 +88,96 @@ class << Diff::LCS::Ldiff
81
88
 
82
89
  # Defaults are for old-style diff
83
90
  @format ||= :old
84
- @lines ||= 0
91
+ @lines ||= 0
85
92
 
86
93
  file_old, file_new = *ARGV
94
+ diff?(
95
+ InputInfo.new(file_old),
96
+ InputInfo.new(file_new),
97
+ @format,
98
+ output,
99
+ binary: @binary,
100
+ lines: @lines
101
+ ) ? 1 : 0
102
+ end
87
103
 
88
- case @format
104
+ def self.diff?(info_old, info_new, format, output, binary: nil, lines: 0)
105
+ case format
89
106
  when :context
90
- char_old = '*' * 3
91
- char_new = '-' * 3
107
+ char_old = "*" * 3
108
+ char_new = "-" * 3
92
109
  when :unified
93
- char_old = '-' * 3
94
- char_new = '+' * 3
110
+ char_old = "-" * 3
111
+ char_new = "+" * 3
95
112
  end
96
113
 
97
114
  # After we've read up to a certain point in each file, the number of
98
115
  # items we've read from each file will differ by FLD (could be 0).
99
116
  file_length_difference = 0
100
117
 
101
- data_old = IO.read(file_old)
102
- data_new = IO.read(file_new)
103
-
104
118
  # Test binary status
105
- if @binary.nil?
106
- old_txt = data_old[0, 4096].scan(/\0/).empty?
107
- new_txt = data_new[0, 4096].scan(/\0/).empty?
108
- @binary = !old_txt || !new_txt
109
- end
110
-
111
- unless @binary
112
- data_old = data_old.lines.to_a
113
- data_new = data_new.lines.to_a
119
+ if binary.nil?
120
+ old_bin = info_old.data[0, 4096].include?("\0")
121
+ new_bin = info_new.data[0, 4096].include?("\0")
122
+ binary = old_bin || new_bin
114
123
  end
115
124
 
116
125
  # diff yields lots of pieces, each of which is basically a Block object
117
- if @binary
118
- diffs = (data_old == data_new)
126
+ if binary
127
+ has_diffs = (info_old.data != info_new.data)
128
+ if format != :report
129
+ if has_diffs
130
+ output << "Binary files #{info_old.filename} and #{info_new.filename} differ\n"
131
+ return true
132
+ end
133
+ return false
134
+ end
119
135
  else
136
+ data_old = info_old.data.lines.to_a
137
+ data_new = info_new.data.lines.to_a
120
138
  diffs = Diff::LCS.diff(data_old, data_new)
121
- diffs = nil if diffs.empty?
139
+ return false if diffs.empty?
122
140
  end
123
141
 
124
- return 0 unless diffs
125
-
126
- if @format == :report
127
- output << "Files #{file_old} and #{file_new} differ\n"
128
- return 1
129
- end
130
-
131
- if (@format == :unified) or (@format == :context)
132
- ft = File.stat(file_old).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.000000000 %z')
133
- output << "#{char_old} #{file_old}\t#{ft}\n"
134
- ft = File.stat(file_new).mtime.localtime.strftime('%Y-%m-%d %H:%M:%S.000000000 %z')
135
- output << "#{char_new} #{file_new}\t#{ft}\n"
142
+ case format
143
+ when :report
144
+ output << "Files #{info_old.filename} and #{info_new.filename} differ\n"
145
+ return true
146
+ when :unified, :context
147
+ ft = info_old.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z")
148
+ output << "#{char_old} #{info_old.filename}\t#{ft}\n"
149
+ ft = info_new.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z")
150
+ output << "#{char_new} #{info_new.filename}\t#{ft}\n"
151
+ when :ed
152
+ real_output = output
153
+ output = []
136
154
  end
137
155
 
138
156
  # Loop over hunks. If a hunk overlaps with the last hunk, join them.
139
157
  # Otherwise, print out the old one.
140
158
  oldhunk = hunk = nil
141
-
142
- if @format == :ed
143
- real_output = output
144
- output = []
145
- end
146
-
147
159
  diffs.each do |piece|
148
- begin # rubocop:disable Style/RedundantBegin
149
- hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, @lines, file_length_difference)
160
+ begin
161
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, lines, file_length_difference)
150
162
  file_length_difference = hunk.file_length_difference
151
163
 
152
164
  next unless oldhunk
153
- next if @lines.positive? and hunk.merge(oldhunk)
165
+ next if lines.positive? && hunk.merge(oldhunk)
154
166
 
155
- output << oldhunk.diff(@format)
156
- output << "\n" if @format == :unified
167
+ output << oldhunk.diff(format)
168
+ output << "\n" if format == :unified
157
169
  ensure
158
170
  oldhunk = hunk
159
171
  end
160
172
  end
161
173
 
162
- last = oldhunk.diff(@format, true)
163
- last << "\n" if last.respond_to?(:end_with?) && !last.end_with?("\n")
174
+ last = oldhunk.diff(format, true)
175
+ last << "\n" unless last.is_a?(Diff::LCS::Hunk) || last.empty? || last.end_with?("\n")
164
176
 
165
177
  output << last
166
178
 
167
- output.reverse_each { |e| real_output << e.diff(:ed_finish) } if @format == :ed
179
+ output.reverse_each { |e| real_output << e.diff(:ed_finish, e == output[0]) } if format == :ed
168
180
 
169
- 1
181
+ true
170
182
  end
171
183
  end