diff_json 0.1.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/diff_json.rb +3 -3
- data/lib/diff_json/diff.rb +77 -479
- data/lib/diff_json/diff/json_diffing.rb +201 -0
- data/lib/diff_json/diff/json_mapping.rb +122 -0
- data/lib/diff_json/output/html_output.rb +268 -0
- data/lib/diff_json/{undefined_value.rb → output/undefined_value.rb} +0 -0
- metadata +27 -12
- data/lib/diff_json/html_output.rb +0 -98
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08af726b4ce91a316f8143a343d18ee82207d95afda7ccd08ad22f9f416cb913'
|
4
|
+
data.tar.gz: 39a56823c4a9ea78ba38f418a3242fc998ae394adaca7e72f09c7b86f07fe306
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93fb867871e15cd864b7558dfe7b6211ce5f1e59c4659c3d4f2f5efb0f2a37d8c041b2a041785d36ec375a7dddf2233030f014ccf1c31b7164985707ad81efbf
|
7
|
+
data.tar.gz: 56e4b5053dca4018508a458fb359075c2e8e3ad738b8ef929843a9430c2f84a7eca6d3377f71493e880f2156b303ab758985e71356d60f454d655bf1179d6f66
|
data/lib/diff_json.rb
CHANGED
data/lib/diff_json/diff.rb
CHANGED
@@ -1,505 +1,103 @@
|
|
1
|
-
|
2
|
-
class Diff
|
3
|
-
def initialize(old_json, new_json, **opts)
|
4
|
-
@old_json = old_json
|
5
|
-
@new_json = new_json
|
6
|
-
@opts = {
|
7
|
-
:debug => false,
|
8
|
-
:diff_count_filter => {
|
9
|
-
:only => ['$**'],
|
10
|
-
:except => []
|
11
|
-
},
|
12
|
-
:ignore_object_keys => [],
|
13
|
-
:generate_object_sub_diffs => {}
|
14
|
-
}.merge(opts)
|
15
|
-
@filtered = @opts[:diff_count_filter] != {
|
16
|
-
:only => ['$**'],
|
17
|
-
:except => []
|
18
|
-
}
|
19
|
-
@diff = {
|
20
|
-
:count => {
|
21
|
-
:all => 0,
|
22
|
-
:insert => 0,
|
23
|
-
:update => 0,
|
24
|
-
:delete => 0,
|
25
|
-
:move => 0
|
26
|
-
},
|
27
|
-
:full_diff => {
|
28
|
-
:old => [],
|
29
|
-
:new => []
|
30
|
-
},
|
31
|
-
:sub_diffs => {}
|
32
|
-
}
|
33
|
-
|
34
|
-
calculate
|
35
|
-
end
|
36
|
-
|
37
|
-
def diff
|
38
|
-
return @diff[:full_diff]
|
39
|
-
end
|
40
|
-
|
41
|
-
def sub_diffs
|
42
|
-
return @diff[:sub_diffs]
|
43
|
-
end
|
44
|
-
|
45
|
-
def change_count(operation = :all)
|
46
|
-
return @diff[:count][operation] || 0
|
47
|
-
end
|
48
|
-
|
49
|
-
def retrieve_output(output_type = :stdout, **output_opts)
|
50
|
-
case output_type
|
51
|
-
when :stdout
|
52
|
-
when :file
|
53
|
-
when :html
|
54
|
-
html_output = HtmlOutput.new(self, **output_opts)
|
55
|
-
return html_output
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def calculate
|
62
|
-
@diff[:full_diff][:old], @diff[:full_diff][:new] = compare_elements(@old_json, @new_json)
|
63
|
-
|
64
|
-
@diff[:sub_diffs].each do |key, sub_diffs|
|
65
|
-
sub_diffs.each do |value, diff|
|
66
|
-
diff[:old] = [] unless diff.key?(:old)
|
67
|
-
diff[:new] = [] unless diff.key?(:new)
|
68
|
-
|
69
|
-
diff[:old], diff[:new] = add_blank_lines(diff[:old], diff[:new])
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def compare_elements(old_element, new_element, indent_step = 0, path = '$')
|
75
|
-
debug([
|
76
|
-
'ENTER compare_elements',
|
77
|
-
"Diffing #{path}"
|
78
|
-
])
|
79
|
-
|
80
|
-
old_element_lines, new_element_lines = [], []
|
1
|
+
require_rel './diff'
|
81
2
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
old_element_lines = JSON.pretty_generate(old_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| [' ', "#{indentation(indent_step)}#{el}"]}
|
86
|
-
new_element_lines = JSON.pretty_generate(new_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| [' ', "#{indentation(indent_step)}#{el}"]}
|
87
|
-
else
|
88
|
-
unless value_type(old_element) == value_type(new_element)
|
89
|
-
debug('Opposite type element, no diff required')
|
90
|
-
|
91
|
-
increment_diff_count(path, :insert)
|
92
|
-
increment_diff_count(path, :delete)
|
93
|
-
old_element_lines, new_element_lines = add_blank_lines(
|
94
|
-
JSON.pretty_generate(old_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| ['-', "#{indentation(indent_step)}#{el}"]},
|
95
|
-
JSON.pretty_generate(new_element, max_nesting: false, quirks_mode: true).split("\n").map{|el| ['+', "#{indentation(indent_step)}#{el}"]}
|
96
|
-
)
|
97
|
-
else
|
98
|
-
debug("Found #{value_type(old_element)}, diffing")
|
99
|
-
|
100
|
-
increment_diff_count(path, :update)
|
101
|
-
old_element_lines, new_element_lines = self.send("#{value_type(old_element)}_diff", old_element, new_element, indent_step, path)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
return old_element_lines, new_element_lines
|
106
|
-
end
|
107
|
-
|
108
|
-
def array_diff(old_array, new_array, indent_step, base_path)
|
109
|
-
debug('ENTER array_diff')
|
110
|
-
|
111
|
-
oal, nal = old_array.length, new_array.length
|
112
|
-
sal = oal < nal ? oal : nal
|
113
|
-
lal = oal > nal ? oal : nal
|
114
|
-
old_array_lines, new_array_lines = [[' ', "#{indentation(indent_step)}["]], [[' ', "#{indentation(indent_step)}["]]
|
115
|
-
next_step = indent_step + 1
|
116
|
-
operations = {
|
117
|
-
'none' => [],
|
118
|
-
'arr_add_index' => [],
|
119
|
-
'arr_drop_index' => [],
|
120
|
-
'arr_send_move' => [],
|
121
|
-
'arr_receive_move' => []
|
122
|
-
}
|
123
|
-
|
124
|
-
# Find indices that were added or dropped, if any
|
125
|
-
if oal < nal
|
126
|
-
operations['arr_add_index'] += (oal..(nal - 1)).to_a
|
127
|
-
elsif oal > nal
|
128
|
-
operations['arr_drop_index'] += (nal..(oal - 1)).to_a
|
129
|
-
end
|
130
|
-
|
131
|
-
# Find 'none' and 'move_value' operations
|
132
|
-
(old_array | new_array).each do |v|
|
133
|
-
# For a given value, find all indices of each array that corresponds
|
134
|
-
old_indices, new_indices = array_indices(old_array, v), array_indices(new_array, v)
|
135
|
-
# Same index, same value, no diff necessary
|
136
|
-
operations['none'] += (old_indices & new_indices)
|
137
|
-
|
138
|
-
# Pull the skipped indices before calculating movements
|
139
|
-
old_indices -= operations['none']
|
140
|
-
new_indices -= operations['none']
|
141
|
-
|
142
|
-
# Find values that were moved from one index to another
|
143
|
-
if !old_indices.empty? and !new_indices.empty?
|
144
|
-
max_moves = old_indices.length < new_indices.length ? old_indices.length : new_indices.length
|
145
|
-
possible_moves = []
|
146
|
-
# Make pairs of possible moves
|
147
|
-
old_indices.each do |oi|
|
148
|
-
new_indices.each do |ni|
|
149
|
-
possible_moves << [(oi - ni).abs, [oi, ni]]
|
150
|
-
end
|
151
|
-
end
|
152
|
-
# For the sake of simplicity, we'll arbitrarily decide to use the shortest moves
|
153
|
-
possible_moves.sort!{|x,y| x[0] <=> y[0]}
|
154
|
-
# Take the first (max_moves) moves and add their operations
|
155
|
-
possible_moves[0..(max_moves - 1)].each do |move|
|
156
|
-
operations['arr_send_move'] << move[1][0]
|
157
|
-
operations['arr_receive_move'] << move[1][1]
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# Add base diff for each index
|
163
|
-
(0..(lal - 1)).each do |i|
|
164
|
-
debug("PROCESS INDEX #{i}")
|
165
|
-
|
166
|
-
item_path = "#{base_path}[#{i}]"
|
167
|
-
old_item_lines, new_item_lines = [], []
|
168
|
-
item_diff_operations = []
|
169
|
-
last_loop = (i == (lal - 1))
|
170
|
-
|
171
|
-
# Assign current known operations to each index
|
172
|
-
(operations.keys).each do |operation|
|
173
|
-
if operations[operation].include?(i)
|
174
|
-
item_diff_operations << operation
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
# Add arr_change_value, arr_add_value, and arr_drop_value operations
|
179
|
-
if item_diff_operations.empty?
|
180
|
-
item_diff_operations << 'arr_change_value'
|
181
|
-
elsif (
|
182
|
-
item_diff_operations.include?('arr_send_move') and
|
183
|
-
!item_diff_operations.include?('arr_receive_move') and
|
184
|
-
!item_diff_operations.include?('arr_drop_index')
|
185
|
-
)
|
186
|
-
item_diff_operations << 'arr_add_value'
|
187
|
-
elsif (
|
188
|
-
!item_diff_operations.include?('arr_send_move') and
|
189
|
-
item_diff_operations.include?('arr_receive_move') and
|
190
|
-
!item_diff_operations.include?('arr_add_index')
|
191
|
-
)
|
192
|
-
item_diff_operations << 'arr_drop_value'
|
193
|
-
end
|
194
|
-
|
195
|
-
# Call compare_elements for sub-elements if necessary
|
196
|
-
if (!(item_diff_operations & ['none', 'arr_change_value']).empty? and
|
197
|
-
is_json_element?(old_array[i]) and is_json_element?(new_array[i])
|
198
|
-
)
|
199
|
-
old_item_lines, new_item_lines = compare_elements(old_array[i], new_array[i], next_step, item_path)
|
200
|
-
else
|
201
|
-
# Grab old and new items
|
202
|
-
# UndefinedValue class is here to represent the difference between explicit null and non-existent
|
203
|
-
old_item = item_diff_operations.include?('arr_add_index') ? UndefinedValue.new : old_array[i]
|
204
|
-
new_item = item_diff_operations.include?('arr_drop_index') ? UndefinedValue.new : new_array[i]
|
205
|
-
|
206
|
-
# Figure out operators for left and right
|
207
|
-
if item_diff_operations.include?('none')
|
208
|
-
old_operator, new_operator = ' ', ' '
|
209
|
-
elsif item_diff_operations.include?('arr_change_value')
|
210
|
-
increment_diff_count(item_path, :update)
|
211
|
-
old_operator, new_operator = '-', '+'
|
212
|
-
elsif (item_diff_operations & ['arr_send_move', 'arr_receive_move']).length == 2
|
213
|
-
increment_diff_count(item_path, :move)
|
214
|
-
old_operator, new_operator = 'M', 'M'
|
215
|
-
elsif item_diff_operations.include?('arr_add_value')
|
216
|
-
increment_diff_count(item_path, :insert)
|
217
|
-
old_operator, new_operator = 'M', '+'
|
218
|
-
elsif item_diff_operations.include?('arr_drop_value')
|
219
|
-
increment_diff_count(item_path, :delete)
|
220
|
-
old_operator, new_operator = '-', 'M'
|
221
|
-
elsif item_diff_operations.include?('arr_drop_index')
|
222
|
-
if item_diff_operations.include?('arr_send_move')
|
223
|
-
increment_diff_count(item_path, :move)
|
224
|
-
old_operator, new_operator = 'M', ' '
|
225
|
-
else
|
226
|
-
increment_diff_count(item_path, :delete)
|
227
|
-
old_operator, new_operator = '-', ' '
|
228
|
-
end
|
229
|
-
elsif item_diff_operations.include?('arr_add_index')
|
230
|
-
if item_diff_operations.include?('arr_receive_move')
|
231
|
-
old_operator, new_operator = ' ', 'M'
|
232
|
-
else
|
233
|
-
increment_diff_count(item_path, :insert)
|
234
|
-
old_operator, new_operator = ' ', '+'
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
# Gather lines
|
239
|
-
if old_item.is_a?(UndefinedValue)
|
240
|
-
new_item_lines = JSON.pretty_generate(new_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [new_operator, "#{indentation(next_step)}#{il}"]}
|
241
|
-
|
242
|
-
(0..(new_item_lines.length - 1)).each do |i|
|
243
|
-
old_item_lines << [' ', '']
|
244
|
-
end
|
245
|
-
else
|
246
|
-
old_item_lines = JSON.pretty_generate(old_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [old_operator, "#{indentation(next_step)}#{il}"]}
|
247
|
-
end
|
248
|
-
|
249
|
-
if new_item.is_a?(UndefinedValue)
|
250
|
-
(0..(old_item_lines.length - 1)).each do |i|
|
251
|
-
new_item_lines << [' ', '']
|
252
|
-
end
|
253
|
-
else
|
254
|
-
new_item_lines = JSON.pretty_generate(new_item, max_nesting: false, quirks_mode: true).split("\n").map{|il| [new_operator, "#{indentation(next_step)}#{il}"]}
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
unless old_item_lines.empty?
|
259
|
-
old_item_lines.last[1] = "#{old_item_lines.last[1]}," if !last_loop and (old_item_lines.last[1].match(/[^\s]/))
|
260
|
-
end
|
261
|
-
unless new_item_lines.empty?
|
262
|
-
new_item_lines.last[1] = "#{new_item_lines.last[1]}," if !last_loop and (new_item_lines.last[1].match(/[^\s]/))
|
263
|
-
end
|
264
|
-
|
265
|
-
add_object_sub_diff_if_required(item_path, old_item, old_item_lines) if old_item.is_a?(Hash) and old_operator == '-'
|
266
|
-
add_object_sub_diff_if_required(item_path, new_item, new_item_lines, :new) if new_item.is_a?(Hash) and new_operator == '+'
|
267
|
-
|
268
|
-
old_item_lines, new_item_lines = add_blank_lines(old_item_lines, new_item_lines)
|
269
|
-
|
270
|
-
old_array_lines += old_item_lines
|
271
|
-
new_array_lines += new_item_lines
|
272
|
-
end
|
273
|
-
|
274
|
-
old_array_lines << [' ', "#{indentation(indent_step)}]"]
|
275
|
-
new_array_lines << [' ', "#{indentation(indent_step)}]"]
|
276
|
-
|
277
|
-
return old_array_lines, new_array_lines
|
278
|
-
end
|
279
|
-
|
280
|
-
def object_diff(old_object, new_object, indent_step, base_path)
|
281
|
-
debug('ENTER object_diff')
|
282
|
-
|
283
|
-
keys = {
|
284
|
-
'all' => (old_object.keys | new_object.keys),
|
285
|
-
'common' => (old_object.keys & new_object.keys),
|
286
|
-
'add' => (new_object.keys - old_object.keys),
|
287
|
-
'drop' => (old_object.keys - new_object.keys)
|
288
|
-
}
|
289
|
-
old_object_lines, new_object_lines = [[' ', "#{indentation(indent_step)}{"]], [[' ', "#{indentation(indent_step)}{"]]
|
290
|
-
next_step = indent_step + 1
|
291
|
-
|
292
|
-
# For objects, we're taking a much simpler approach, so no movements
|
293
|
-
keys['all'].each do |k|
|
294
|
-
debug("PROCESS KEY #{k}")
|
295
|
-
|
296
|
-
item_path = "#{base_path}{#{k}}"
|
297
|
-
key_string = "#{JSON.pretty_generate(k, max_nesting: false, quirks_mode: true)}: "
|
298
|
-
old_item_lines, new_item_lines = [], []
|
299
|
-
last_loop = (k == keys['all'].last)
|
300
|
-
|
301
|
-
if keys['common'].include?(k)
|
302
|
-
if is_json_element?(old_object[k]) and is_json_element?(new_object[k]) and !@opts[:ignore_object_keys].include?(k)
|
303
|
-
old_item_lines, new_item_lines = compare_elements(old_object[k], new_object[k], next_step, item_path)
|
304
|
-
else
|
305
|
-
if old_object[k] == new_object[k] or @opts[:ignore_object_keys].include?(k)
|
306
|
-
old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [' ', "#{indentation(next_step)}#{il}"]}
|
307
|
-
new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [' ', "#{indentation(next_step)}#{il}"]}
|
308
|
-
else
|
309
|
-
increment_diff_count(item_path, :update)
|
310
|
-
old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| ['-', "#{indentation(next_step)}#{il}"]}
|
311
|
-
new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| ['+', "#{indentation(next_step)}#{il}"]}
|
312
|
-
end
|
313
|
-
end
|
314
|
-
else
|
315
|
-
if keys['drop'].include?(k)
|
316
|
-
increment_diff_count(item_path, :delete) unless @opts[:ignore_object_keys].include?(k)
|
317
|
-
old_item_lines = JSON.pretty_generate(old_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [@opts[:ignore_object_keys].include?(k) ? ' ' : '-', "#{indentation(next_step)}#{il}"]}
|
318
|
-
new_item_lines = []
|
319
|
-
|
320
|
-
(0..(old_item_lines.length - 1)).each do |i|
|
321
|
-
new_item_lines << [' ', '']
|
322
|
-
end
|
323
|
-
elsif keys['add'].include?(k)
|
324
|
-
increment_diff_count(item_path, :insert) unless @opts[:ignore_object_keys].include?(k)
|
325
|
-
new_item_lines = JSON.pretty_generate(new_object[k], max_nesting: false, quirks_mode: true).split("\n").map!{|il| [@opts[:ignore_object_keys].include?(k) ? ' ' : '+', "#{indentation(next_step)}#{il}"]}
|
326
|
-
old_item_lines = []
|
3
|
+
module DiffJson
|
4
|
+
def self.diff(old_json, new_json, return_type, diff_opts = {}, output_opts = {})
|
5
|
+
completed_diff = Diff.new(old_json, new_json, **diff_opts)
|
327
6
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
7
|
+
return case return_type
|
8
|
+
when :raw
|
9
|
+
completed_diff
|
10
|
+
when :patch
|
11
|
+
patch_operations = []
|
333
12
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
338
|
-
unless new_item_lines.empty?
|
339
|
-
new_item_lines[0][1].gsub!(/^(?<spaces>\s+)(?<content>.+)$/, "\\k<spaces>#{key_string}\\k<content>")
|
340
|
-
new_item_lines.last[1] = "#{new_item_lines.last[1]}," if !last_loop and (new_item_lines.last[1].match(/[^\s]/))
|
13
|
+
completed_diff.diff.each do |path, operations|
|
14
|
+
operations.each do |op|
|
15
|
+
patch_operations << op if [:add, :replace, :remove].include?(op[:op]) or (op[:op] == :move and path == op[:from])
|
341
16
|
end
|
342
|
-
|
343
|
-
old_item_lines, new_item_lines = add_blank_lines(old_item_lines, new_item_lines)
|
344
|
-
|
345
|
-
old_object_lines += old_item_lines
|
346
|
-
new_object_lines += new_item_lines
|
347
17
|
end
|
348
18
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
add_object_sub_diff_if_required(base_path, old_object, old_object_lines)
|
353
|
-
add_object_sub_diff_if_required(base_path, new_object, new_object_lines, :new)
|
354
|
-
|
355
|
-
return old_object_lines, new_object_lines
|
356
|
-
end
|
357
|
-
|
358
|
-
def debug(message)
|
359
|
-
puts message if @opts[:debug]
|
360
|
-
end
|
361
|
-
|
362
|
-
def array_indices(array, value)
|
363
|
-
indices = []
|
364
|
-
|
365
|
-
array.each_with_index do |av,i|
|
366
|
-
indices << i if av == value
|
367
|
-
end
|
368
|
-
|
369
|
-
return indices
|
19
|
+
return patch_operations
|
20
|
+
when :html
|
21
|
+
HtmlOutput.new(completed_diff, **output_opts)
|
370
22
|
end
|
23
|
+
end
|
371
24
|
|
372
|
-
|
373
|
-
|
374
|
-
|
25
|
+
class Diff
|
26
|
+
include JsonMapping
|
27
|
+
include JsonDiffing
|
375
28
|
|
376
|
-
def
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
29
|
+
def initialize(old_json, new_json, **opts)
|
30
|
+
# Set config options
|
31
|
+
@opts = {
|
32
|
+
count_operations: {
|
33
|
+
'/**' => [:add, :replace, :remove, :move, :update]
|
34
|
+
},
|
35
|
+
ignore_paths: [],
|
36
|
+
path_sort: :sorted,
|
37
|
+
sub_diffs: {},
|
38
|
+
track_array_moves: true,
|
39
|
+
track_structure_updates: false,
|
40
|
+
replace_primitives_arrays: false,
|
41
|
+
logger: ::Logger.new(STDOUT),
|
42
|
+
log_level: :warn
|
43
|
+
}.merge(opts)
|
44
|
+
# Create map of both JSON objects
|
45
|
+
@old_map = map_json(old_json, '', 0)
|
46
|
+
@new_map = map_json(new_json, '', 0)
|
47
|
+
# Gather the full list of all paths in both JSON objects in a consistent order
|
48
|
+
@all_paths = gather_paths(@old_map.keys, @new_map.keys, @opts[:path_sort] == :sorted)
|
49
|
+
# Generate diff operations list
|
50
|
+
@diff = diff_check(old_json, new_json)
|
51
|
+
# Find difference counts
|
52
|
+
@counts = find_counts(@diff)
|
53
|
+
# Gather sub-diffs
|
54
|
+
@sub_diffs = generate_sub_diffs
|
55
|
+
end
|
56
|
+
|
57
|
+
def count(count_type = :all)
|
58
|
+
return case count_type
|
59
|
+
when :ignore, :add, :replace, :remove, :move, :update
|
60
|
+
@counts[count_type] || 0
|
61
|
+
when :total
|
62
|
+
@counts.values.sum
|
384
63
|
else
|
385
|
-
|
64
|
+
@counts
|
386
65
|
end
|
387
66
|
end
|
388
67
|
|
389
|
-
def
|
390
|
-
|
391
|
-
' ' * step
|
68
|
+
def diff
|
69
|
+
return @diff
|
392
70
|
end
|
393
71
|
|
394
|
-
def
|
395
|
-
|
396
|
-
(1..(right_lines.length - left_lines.length)).each do
|
397
|
-
left_lines << [' ', '']
|
398
|
-
end
|
399
|
-
elsif left_lines.length > right_lines.length
|
400
|
-
(1..(left_lines.length - right_lines.length)).each do
|
401
|
-
right_lines << [' ', '']
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
return left_lines, right_lines
|
72
|
+
def json_map(version = :old)
|
73
|
+
return (version == :old ? @old_map : @new_map)
|
406
74
|
end
|
407
75
|
|
408
|
-
def
|
409
|
-
|
410
|
-
|
76
|
+
def paths(version = :joint)
|
77
|
+
return case version
|
78
|
+
when :old
|
79
|
+
json_map(:old).keys
|
80
|
+
when :new
|
81
|
+
json_map(:new).keys
|
411
82
|
else
|
412
|
-
|
413
|
-
|
414
|
-
# Any path prefixes in `only` that match?
|
415
|
-
if (
|
416
|
-
@opts[:diff_count_filter].key?(:only) and
|
417
|
-
@opts[:diff_count_filter][:only].is_a?(Array) and
|
418
|
-
!@opts[:diff_count_filter][:only].empty?
|
419
|
-
)
|
420
|
-
@opts[:diff_count_filter][:only].each do |only_path|
|
421
|
-
unless ['none', 'lower'].include?(path_inclusion(path, only_path))
|
422
|
-
do_count = true
|
423
|
-
break
|
424
|
-
else
|
425
|
-
next
|
426
|
-
end
|
427
|
-
end
|
428
|
-
else
|
429
|
-
# If :only is empty or non-existent, count everything
|
430
|
-
do_count = true
|
431
|
-
end
|
432
|
-
|
433
|
-
# Make sure the specific path is not excluded, if we've established that we should probably include it
|
434
|
-
if (
|
435
|
-
do_count and
|
436
|
-
@opts[:diff_count_filter].key?(:except) and
|
437
|
-
@opts[:diff_count_filter][:except].is_a?(Array) and
|
438
|
-
!@opts[:diff_count_filter][:except].empty?
|
439
|
-
)
|
440
|
-
@opts[:diff_count_filter][:except].each do |except_path|
|
441
|
-
unless ['none', 'lower'].include?(path_inclusion(path, except_path))
|
442
|
-
do_count = false
|
443
|
-
break
|
444
|
-
else
|
445
|
-
next
|
446
|
-
end
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
|
-
# Ensure this operation is allowed for counting
|
451
|
-
if (
|
452
|
-
do_count and
|
453
|
-
@opts[:diff_count_filter].key?(:operations) and
|
454
|
-
@opts[:diff_count_filter][:operations].is_a?(Array)
|
455
|
-
)
|
456
|
-
do_count = false if (
|
457
|
-
!@opts[:diff_count_filter][:operations].empty? and
|
458
|
-
!@opts[:diff_count_filter][:operations].include?(operation)
|
459
|
-
)
|
460
|
-
end
|
461
|
-
|
462
|
-
debug("Post-operation, #{do_count}")
|
463
|
-
|
464
|
-
@diff[:count][:all] += 1 if do_count
|
465
|
-
@diff[:count][operation] += 1 if do_count
|
83
|
+
@all_paths
|
466
84
|
end
|
467
85
|
end
|
468
86
|
|
469
|
-
def
|
470
|
-
|
471
|
-
check_path_wildcard = check_path.gsub(/[^\*]/, '') || ''
|
472
|
-
check = 'lower'
|
473
|
-
|
474
|
-
if current_path == check_path_base
|
475
|
-
check = 'exact' if check_path_wildcard == ''
|
476
|
-
check = 'lower'
|
477
|
-
elsif current_path.include?(check_path_base)
|
478
|
-
current_path_remainder = current_path.gsub(check_path_base, '')
|
479
|
-
current_path_remainder_steps = current_path_remainder.split(/(\]\[|\]\{|\}\[|\}\{)/)
|
480
|
-
|
481
|
-
check = 'level' if (current_path_remainder_steps.length == 1 and check_path_wildcard == '*')
|
482
|
-
check = 'recurse' if (current_path_remainder_steps.length > 0 and check_path_wildcard == '**')
|
483
|
-
else
|
484
|
-
check = 'none'
|
485
|
-
end
|
486
|
-
|
487
|
-
return check
|
87
|
+
def sub_diffs
|
88
|
+
return @sub_diffs
|
488
89
|
end
|
489
90
|
|
490
|
-
def
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
@diff[:sub_diffs][v][object[v]][side] = lines if object.key?(v)
|
501
|
-
end
|
502
|
-
end
|
91
|
+
def log_message(log_level, message)
|
92
|
+
log_levels = [
|
93
|
+
:debug,
|
94
|
+
:info,
|
95
|
+
:warn,
|
96
|
+
:error
|
97
|
+
]
|
98
|
+
|
99
|
+
if (log_levels.index(log_level) || -1) >= (log_levels.index(@opts[:log_level]) || 0)
|
100
|
+
@opts[:logger].method(log_level).call((is_structure?(message) ? JSON.pretty_generate(message) : message))
|
503
101
|
end
|
504
102
|
end
|
505
103
|
end
|