diff-lcs 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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