overrides_tracker 0.1.8 → 0.1.12

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