overrides_tracker 0.1.9 → 0.1.12

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,115 +1,349 @@
1
1
  class OverridesTracker::Comparer
2
2
  DO_BASE_DIR = File.join(Dir.pwd, "/overrides_tracker")
3
3
 
4
- def self.compare
5
- all_methods_collections = {}
6
- unified_methods_collections = {}
7
- report_files = Dir.entries(DO_BASE_DIR) - [".", ".."]
8
- report_files.each do |file_name|
9
- if file_name[-4..-1] == '.otf'
10
- all_methods_collections[file_name] = {}
11
- method_collection = OverridesTracker::MethodsCollector.instance.load_from_file(file_name)
12
- all_methods_collections[file_name] = method_collection
13
- unified_methods_collections = unified_methods_collections.deep_merge(method_collection)
14
- end
15
- end
16
-
4
+ def self.compare_builds(unified_methods_collections, all_methods_collections, working_directories, bundle_directories)
17
5
  same_source_count = 0
18
6
  errored_source_count = 0
19
7
  method_not_available_count = 0
20
8
  method_not_override_count = 0
21
9
  source_changed_count = 0
22
-
23
10
  methods_count = 0
24
11
  classes_count = 0
25
12
 
26
- unified_methods_collections.each do |unified_class_name, unified_class_hash|
13
+ results = []
14
+ added_method_results = []
27
15
 
28
- if unified_class_hash['instance_methods'].any? || unified_class_hash['singleton_methods'].any?
29
- classes_count +=1
30
- ['instance_methods', 'singleton_methods'].each do |method_type|
31
- unified_class_hash[method_type].each do |unified_method_name, unified_method_hash|
16
+ numbers = {}
17
+ numbers[:overrides] = {}
18
+ numbers[:overrides][:source_changed_count] = 0
19
+ numbers[:overrides][:override_changed_count] = 0
20
+ numbers[:overrides][:method_not_available_count] = 0
21
+ numbers[:overrides][:method_not_override_count] = 0
22
+ numbers[:overrides][:total] = 0
23
+
24
+ numbers[:added_methods] = {}
25
+ numbers[:added_methods][:source_changed_count] = 0
26
+ numbers[:added_methods][:override_changed_count] = 0
27
+ numbers[:added_methods][:method_not_available_count] = 0
28
+ numbers[:added_methods][:method_not_override_count] = 0
29
+ numbers[:added_methods][:total] = 0
30
+ numbers[:total] = {}
32
31
 
33
- methods_count += 1
34
- puts ""
35
- puts "==========================================================================================="
36
- puts ""
32
+
33
+ unified_methods_collections.each do |unified_class_name, unified_class_hash|
34
+ if unified_class_hash['instance_methods']&.any? || unified_class_hash['singleton_methods']&.any?
35
+ ['instance_methods', 'singleton_methods'].each do |method_type|
36
+ unified_class_hash[method_type]&.each do |unified_method_name, unified_method_hash|
37
37
  same_source_every_where = true
38
38
 
39
-
40
- all_methods_collections.each do |file_name, all_methods_hash|
41
- if all_methods_hash[unified_class_name].nil? || all_methods_hash[unified_class_name][method_type][unified_method_name].nil? || all_methods_hash[unified_class_name][method_type][unified_method_name]['sha'] != unified_method_hash['sha']
39
+ all_methods_collections.each do |build_id, all_methods_hash|
40
+ if all_methods_hash[unified_class_name].nil? ||
41
+ all_methods_hash[unified_class_name][method_type].nil? ||
42
+ all_methods_hash[unified_class_name][method_type][unified_method_name].nil? ||
43
+ all_methods_hash[unified_class_name][method_type][unified_method_name]['sha'] != unified_method_hash['sha'] ||
44
+ all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_sha'] != unified_method_hash['overriding_sha']
42
45
  same_source_every_where = false
43
46
  end
44
47
  end
45
48
 
49
+ method_result_hash = {class_name: unified_class_name, method_name: unified_method_name, builds: {}, method_type: method_type, changes_detected: false}
50
+
46
51
  if same_source_every_where
47
- puts "#{methods_count}) #{unified_class_name}##{unified_method_name}: No Changes".green.bold
48
- same_source_count += 1
52
+ results << method_result_hash
49
53
  else
50
- errored_output = nil
54
+ method_result_hash[:changes_detected] = true
55
+ method_result_hash[:builds] ||= {}
56
+
57
+ is_source_changed_flag = false
58
+ is_override_changed_flag = false
59
+ all_methods_collections.each do |build_id, all_methods_hash|
60
+
61
+ method_result_hash[:builds][build_id] ||= {}
62
+
63
+ if all_methods_hash[unified_class_name].nil?
51
64
 
52
- puts "#{methods_count}) #{unified_class_name}##{unified_method_name}: Changes between files".red.bold
65
+ method_result_hash[:builds][build_id] = {result: 'method_not_available'}
66
+ numbers[:overrides][:method_not_available_count] +=1
67
+
68
+ elsif all_methods_hash[unified_class_name][method_type].nil?
69
+ if all_methods_hash[unified_class_name]["added_#{method_type}"]
70
+ if all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name]
71
+ method_result_hash[:builds][build_id] = {result: 'method_not_override', data: all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name]}
72
+ numbers[:overrides][:method_not_override_count] +=1
73
+ end
74
+ end
75
+ elsif !all_methods_hash[unified_class_name][method_type][unified_method_name].nil?
76
+ if all_methods_hash[unified_class_name][method_type][unified_method_name]['sha'] != unified_method_hash['sha']
77
+ method_result_hash[:builds][build_id] = {result: 'source_has_changed'}
78
+ method_result_hash[:builds][build_id][:original_body] = all_methods_hash[unified_class_name][method_type][unified_method_name]['body']
79
+ method_result_hash[:builds][build_id][:original_sha] = all_methods_hash[unified_class_name][method_type][unified_method_name]['sha']
80
+ method_result_hash[:builds][build_id][:original_location] = all_methods_hash[unified_class_name][method_type][unified_method_name]['location']
81
+ method_result_hash[:builds][build_id][:overriding_body] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_body']
82
+ method_result_hash[:builds][build_id][:overriding_location] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_location']
83
+ method_result_hash[:builds][build_id][:overriding_sha] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_sha']
84
+ method_result_hash[:builds][build_id][:is_part_of_app] = all_methods_hash[unified_class_name][method_type][unified_method_name]['is_part_of_app'] || all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_is_part_of_app']
85
+ mask_path(method_result_hash[:builds][build_id], working_directories[build_id], bundle_directories[build_id])
86
+
87
+ numbers[:overrides][:source_changed_count] += 1
88
+ is_source_changed_flag = true
89
+ is_override_changed_flag = false
90
+ else
91
+ method_result_hash[:builds][build_id] = {result: 'override_has_changed'}
92
+ method_result_hash[:builds][build_id][:original_body] = all_methods_hash[unified_class_name][method_type][unified_method_name]['body']
93
+ method_result_hash[:builds][build_id][:original_sha] = all_methods_hash[unified_class_name][method_type][unified_method_name]['sha']
94
+ method_result_hash[:builds][build_id][:original_location] = all_methods_hash[unified_class_name][method_type][unified_method_name]['location']
95
+ method_result_hash[:builds][build_id][:overriding_body] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_body']
96
+ method_result_hash[:builds][build_id][:overriding_location] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_location']
97
+ method_result_hash[:builds][build_id][:overriding_sha] = all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_sha']
98
+ method_result_hash[:builds][build_id][:is_part_of_app] = all_methods_hash[unified_class_name][method_type][unified_method_name]['is_part_of_app'] || all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_is_part_of_app']
99
+
100
+ mask_path(method_result_hash[:builds][build_id], working_directories[build_id], bundle_directories[build_id])
101
+
102
+ numbers[:overrides][:override_changed_count] += 1
103
+ is_override_changed_flag = true
104
+ end
105
+ else
106
+ method_result_hash[:builds][build_id] = {result: 'method_not_available'}
107
+ numbers[:overrides][:method_not_available_count] +=1
108
+ end
109
+ end
110
+
111
+ if is_source_changed_flag
112
+ line_differerence_array = []
113
+ all_methods_collections.each do |build_id, all_methods_hash|
114
+
115
+ line_differerence_array << method_result_hash[:builds][build_id][:original_body].split(/\n/)
116
+
117
+ if method_result_hash[:builds][build_id][:result] == 'override_has_changed'
118
+ numbers[:overrides][:override_changed_count] -= 1
119
+ numbers[:overrides][:source_changed_count] += 1
120
+ end
121
+ method_result_hash[:builds][build_id][:result] = 'source_has_changed'
122
+ end
123
+
124
+ max_length = line_differerence_array.map(&:length).max
125
+ transposed_array = line_differerence_array.map{|e| e.values_at(0...max_length)}.transpose
126
+ method_result_hash[:mark_lines] = transposed_array.map.with_index{|val, index| val.uniq.size > 1 ? index : nil}.compact
127
+ is_override_changed_flag = false
128
+ end
129
+
130
+ if is_override_changed_flag
131
+ line_differerence_array = []
132
+ begin
133
+
134
+ all_methods_collections.each do |build_id, all_methods_hash|
135
+ line_differerence_array << method_result_hash[:builds][build_id][:overriding_body].split(/\n/)
136
+ end
137
+
138
+ max_length = line_differerence_array.map(&:length).max
139
+ transposed_array = line_differerence_array.map{|e| e.values_at(0...max_length)}.transpose
140
+ method_result_hash[:overriding_mark_lines] = transposed_array.map.with_index{|val, index| val.uniq.size > 1 ? index : nil}.compact
141
+ rescue => exception
142
+
143
+ end
144
+
145
+ end
146
+
147
+ method_result_hash[:is_part_of_app] = method_result_hash[:builds].select{|bu, bu_val| bu_val[:is_part_of_app] }.any?
148
+
149
+ results << method_result_hash
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+
156
+ if unified_class_hash['added_instance_methods']&.any? || unified_class_hash['added_singleton_methods']&.any?
157
+
158
+ ['added_instance_methods', 'added_singleton_methods'].each do |method_type|
159
+ unified_class_hash[method_type]&.each do |unified_method_name, unified_method_hash|
160
+
161
+ same_source_every_where = true
162
+
163
+ is_added_source_has_changed_flag = false
164
+
165
+ all_methods_collections.each do |build_id, all_methods_hash|
166
+ unless (all_methods_hash[unified_class_name] != nil) && (all_methods_hash[unified_class_name][method_type] != nil) && (all_methods_hash[unified_class_name][method_type][unified_method_name] != nil ) && (all_methods_hash[unified_class_name][method_type][unified_method_name]['sha'] == unified_method_hash['sha'])
167
+ same_source_every_where = false
168
+ end
169
+ end
170
+
171
+ method_result_hash = {class_name: unified_class_name, method_name: unified_method_name, builds: {}, method_type: method_type, changes_detected: false}
172
+
173
+ if same_source_every_where
174
+ added_method_results << method_result_hash
175
+ else
176
+ method_result_hash[:changes_detected] = true
177
+ method_result_hash[:builds] ||= {}
53
178
 
54
- all_methods_collections.each do |file_name, all_methods_hash|
55
- puts ""
56
- puts ("in: "+file_name).bold
179
+ all_methods_collections.each do |build_id, all_methods_hash|
180
+
181
+ method_result_hash[:builds][build_id] ||= {}
57
182
 
58
- if all_methods_hash[unified_class_name].nil?
59
- puts "#{unified_class_name}##{unified_method_name}: method is not in codebase"
60
- method_not_available_count +=1
183
+ if all_methods_hash[unified_class_name].nil?
184
+ method_result_hash[:builds][build_id] = {result: 'added_method_not_available'}
185
+ numbers[:added_methods][:method_not_available_count] +=1
186
+ elsif all_methods_hash[unified_class_name][method_type].nil?
187
+ method_result_hash[:builds][build_id] = {result: 'added_method_not_available'}
188
+ numbers[:added_methods][:method_not_available_count] +=1
61
189
  elsif !all_methods_hash[unified_class_name][method_type][unified_method_name].nil?
62
- puts "#{unified_class_name}##{unified_method_name}:"
63
- puts ""
64
- puts "Source:".bold
65
- puts "#{all_methods_hash[unified_class_name][method_type][unified_method_name]['body']}"
66
- puts ""
67
- puts "#{all_methods_hash[unified_class_name][method_type][unified_method_name]['location'][0]}:#{all_methods_hash[unified_class_name][method_type][unified_method_name]['location'][1]}".italic
68
-
69
- puts ""
70
- puts "Override:".bold
71
- puts "#{all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_body']}"
72
- puts ""
73
- puts "#{all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_location'][0]}:#{all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_location'][1]}".italic
74
-
75
- source_changed_count +=1
76
- elsif !all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name].nil?
77
- puts "#{unified_class_name}##{unified_method_name}: method is not an override"
78
- method_not_override_count +=1
79
-
80
- puts ""
81
- puts "Code:".bold
82
- puts "#{all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name]['body']}"
83
- puts ""
84
- # puts "#{all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name]['location'][0]}:#{all_methods_hash[unified_class_name][method_type][unified_method_name]['location'][1]}".italic
85
-
86
- elsif all_methods_hash[unified_class_name]["added_#{method_type}"][unified_method_name].nil?
87
- puts "#{unified_class_name}##{unified_method_name}: method is not in codebase"
88
- method_not_available_count +=1
190
+ method_result_hash[:builds][build_id] = {result: 'added_source_has_changed'}
191
+ method_result_hash[:builds][build_id][:original_body] = all_methods_hash[unified_class_name][method_type][unified_method_name]['body']
192
+ method_result_hash[:builds][build_id][:original_location] = all_methods_hash[unified_class_name][method_type][unified_method_name]['location']
193
+ method_result_hash[:builds][build_id][:is_part_of_app] = all_methods_hash[unified_class_name][method_type][unified_method_name]['is_part_of_app'] || all_methods_hash[unified_class_name][method_type][unified_method_name]['overriding_is_part_of_app']
194
+
195
+ mask_path(method_result_hash[:builds][build_id], working_directories[build_id], bundle_directories[build_id])
196
+
197
+ numbers[:added_methods][:source_changed_count] += 1
198
+ is_added_source_has_changed_flag = true
199
+ elsif all_methods_hash[unified_class_name][method_type][unified_method_name].nil?
200
+ method_result_hash[:builds][build_id] = {result: 'added_method_not_available'}
201
+ numbers[:added_methods][:method_not_available_count] +=1
89
202
  else
90
- puts "#{unified_class_name}##{unified_method_name}: #{all_methods_hash[unified_class_name][method_type][unified_method_name]}"
203
+ method_result_hash[:builds][build_id] = {result: 'error'}
91
204
  end
92
- puts ""
93
-
94
205
  end
95
- errored_source_count += 1
206
+
207
+ if is_added_source_has_changed_flag
208
+ begin
209
+
210
+ line_differerence_array = []
211
+ all_methods_collections.each do |build_id, all_methods_hash|
212
+ line_differerence_array << method_result_hash[:builds][build_id][:original_body].split(/\n/)
213
+ end
214
+
215
+ max_length = line_differerence_array.map(&:length).max
216
+ transposed_array = line_differerence_array.map{|e| e.values_at(0...max_length)}.transpose
217
+ method_result_hash[:mark_added_method_lines] = transposed_array.map.with_index{|val, index| val.uniq.size > 1 ? index : nil}.compact
218
+ rescue
219
+
220
+ end
221
+ end
222
+
223
+ method_result_hash[:is_part_of_app] = method_result_hash[:builds].select{|bu, bu_val| bu_val[:is_part_of_app] }.any?
224
+ added_method_results << method_result_hash
225
+
96
226
  end
97
227
  end
98
- end
228
+ end
229
+ end
230
+ end
231
+
232
+ numbers[:overrides][:total] = numbers[:overrides][:method_not_override_count] + numbers[:overrides][:method_not_available_count] + numbers[:overrides][:source_changed_count] + numbers[:overrides][:override_changed_count]
233
+ numbers[:added_methods][:total] = numbers[:added_methods][:method_not_available_count] + numbers[:added_methods][:source_changed_count]
234
+ numbers[:total] = numbers[:overrides][:total] + numbers[:added_methods][:total]
235
+
236
+ {results: {override_results: results, added_method_results: added_method_results}, numbers: numbers}
237
+ end
238
+
239
+ def self.mask_path(build_hash, working_directory, bundle_directory)
240
+ if build_hash[:original_location]
241
+ build_hash[:original_location][0].gsub!(working_directory, 'APP_PATH')
242
+ build_hash[:original_location][0].gsub!(bundle_directory, 'BUNDLE_PATH')
243
+ end
244
+
245
+ if build_hash[:overriding_location]
246
+ build_hash[:overriding_location][0].gsub!(working_directory, 'APP_PATH')
247
+ build_hash[:overriding_location][0].gsub!(bundle_directory, 'BUNDLE_PATH')
248
+ end
249
+ end
250
+
251
+ def self.compare
252
+ all_methods_collections = {}
253
+ unified_methods_collections = {}
254
+ working_directories = {}
255
+ bundle_directories = {}
256
+
257
+ all_methods_collections = {}
258
+ unified_methods_collections = {}
259
+ report_files = Dir.entries(DO_BASE_DIR) - [".", ".."]
260
+ report_files.each do |file_name|
261
+ if file_name[-4..-1] == '.otf'
262
+ all_methods_collections[file_name] = {}
263
+ result_file_data = OverridesTracker::MethodsCollector.instance.load_from_file(file_name)
264
+ result_file_data.deep_stringify_keys!
265
+ methods_collection = result_file_data['methods_collection']
266
+ all_methods_collections[file_name] = methods_collection
267
+ working_directories[file_name] = result_file_data['working_directory']
268
+ bundle_directories[file_name] = result_file_data['bundle_path']
269
+ unified_methods_collections = unified_methods_collections.deep_merge(methods_collection)
270
+ end
271
+ end
272
+
273
+ comparison = compare_builds(unified_methods_collections, all_methods_collections, working_directories, bundle_directories)
274
+ methods_count = 0
275
+
276
+ comparison[:results].each do |result_type, result_array|
277
+ result_array.each do |method_hash|
278
+ if method_hash[:builds] != {}
279
+ methods_count += 1
280
+ puts ""
281
+ puts "==========================================================================================="
282
+ puts ""
283
+ if result_type == :override_results
284
+ puts "#{methods_count}) Override: #{method_hash[:class_name]}##{method_hash[:method_name]}".bold
285
+ else
286
+ puts "#{methods_count}) Added Method: #{method_hash[:class_name]}##{method_hash[:method_name]}".bold
287
+ end
288
+
289
+ method_hash[:builds].each do |build_id, build_result|
290
+ puts ''
291
+ puts "..........................................................................................."
292
+ puts ''
293
+ puts build_id
294
+ if build_result[:result] == 'source_has_changed'
295
+ puts ""
296
+ elsif build_result[:result] == 'method_not_override'
297
+ puts "Method not override".italic.yellow
298
+ elsif build_result[:result] == 'method_not_available'
299
+ puts "Method not available".italic.yellow
300
+ elsif build_result[:result] == 'added_method_not_available'
301
+ puts "Added method not available".italic.yellow
302
+ elsif build_result[:result] == 'added_source_has_changed'
303
+ puts ''
304
+ end
305
+
306
+
307
+ unless build_result[:original_body].nil?
308
+ puts "-------------------------------------------------------------------------------------------".pink
309
+ puts ''
310
+ puts 'Original:'.italic
311
+ puts ''
312
+ puts "#{build_result[:original_body]}".pink
313
+ puts ''
314
+ puts "in #{build_result[:original_location][0]}:#{build_result[:original_location][1]}".italic
315
+ end
316
+ puts ''
317
+ puts ''
318
+ unless build_result[:overriding_body].nil?
319
+ puts "-------------------------------------------------------------------------------------------".blue
320
+ puts ''
321
+ puts 'Override:'.italic
322
+ puts ''
323
+ puts "#{build_result[:overriding_body]}".blue
324
+ puts ''
325
+ puts "in: #{build_result[:overriding_location][0]}:#{build_result[:overriding_location][1]}".italic
326
+ end
327
+
328
+ puts ''
329
+ puts ''
330
+ end
331
+ end
99
332
  end
100
333
  end
101
334
 
335
+
102
336
  puts ""
103
337
  puts "==========================================================================================="
104
338
  puts ""
105
339
  puts "Summary:".bold
106
- puts "Found #{methods_count} distinct overridden methods in #{classes_count} Files"
107
- puts "#{same_source_count} overridden methods have not changed"
108
- puts "#{errored_source_count} overridden methods have changed"
109
- puts "#{method_not_override_count} where method is not an override"
110
- puts "#{method_not_available_count} where method is not in codebase"
111
- source_changed_count = errored_source_count - method_not_available_count
112
- puts "#{source_changed_count} source method bodies have changed"
340
+ puts ""
341
+ puts "Investigated methods: #{comparison[:numbers][:total]/2}"
342
+ puts "Diffences on overrides: #{comparison[:numbers][:overrides][:total]/2}"
343
+ puts "Diffences on added methods: #{comparison[:numbers][:added_methods][:total]/2}"
344
+
345
+ comparison
113
346
  end
347
+
114
348
  end
115
349
 
@@ -7,4 +7,4 @@ module OverridesTracker::FileObserver
7
7
  end
8
8
  end
9
9
  end
10
- end
10
+ end