git_ownership_insights 1.0.3 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8e4215542d1b1f05793def9ec7da4bf9c9cbdcc8b8fd0e00a912188ce877b85
4
- data.tar.gz: 0b10b78de68c0f71013a9d6a9458b45dd824ed283bd3b0613c93f3146b0d1fc8
3
+ metadata.gz: dc9c0c038149e42cd56b515168124dd68d50476169deedd38e98cb8593770106
4
+ data.tar.gz: bc3e24fb12aac9bf7e94e6649b61b4941d1dfba20a7cc23f4ba56e566631faa1
5
5
  SHA512:
6
- metadata.gz: f0cd127fa863e8d06d868527b5d3f2ea662f560d6149f95bbef1df18ed3442c7d08b6eb27aa4ed8e223c5bdbb2772a37aa1c8de41fb6920e5f96d7fd3555e833
7
- data.tar.gz: 58fcc55d06921ce4c57c008496c82af548992d2e007b24d3449a2b51b1957ac41aa5a0a87bf809d7435814cf5273e8e70aff80659bc5786772e4c8a144687ae3
6
+ metadata.gz: 7638cb2568573d64238ba56438b9bb70e7a7ec6c9d28ac353e79c867d174039c04237103fc424cadd146d169bbce2014a8651445cc660ae2b7a06a7126bdb7cd
7
+ data.tar.gz: 5941142ba797b288b7a82e5a5b20edf91eb2c00cf754375743eccbb70e0ad31b8ce111f03f1c238746724d096f686b3f0b786c75432d3571e9b290eea7ae1284
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- git_ownership_insights (0.1.4)
5
- awesome_print
4
+ git_ownership_insights (1.0.4)
6
5
  date
7
6
  pry
8
7
 
@@ -10,7 +9,6 @@ GEM
10
9
  remote: https://rubygems.org/
11
10
  specs:
12
11
  ast (2.4.2)
13
- awesome_print (1.9.2)
14
12
  coderay (1.1.3)
15
13
  date (3.3.4)
16
14
  diff-lcs (1.5.0)
@@ -10,11 +10,11 @@ options = {}
10
10
  OptionParser.new do |opts|
11
11
  opts.banner = 'Usage: git_ownership_insights [options]'
12
12
 
13
- opts.on('-d', '--debug', 'Enable debug mode') do
13
+ opts.on('--debug', 'Enable debug mode') do
14
14
  options[:debug] = true
15
15
  end
16
16
 
17
- opts.on('-ci', '--ci', 'Do not print the info messages for better CI text parsing [default: false]') do
17
+ opts.on('--ci', 'Do not print the info messages for better CI text parsing [default: false]') do
18
18
  options[:ci] = true
19
19
  end
20
20
 
@@ -22,56 +22,56 @@ OptionParser.new do |opts|
22
22
  options[:codeowners] = true
23
23
  end
24
24
 
25
- opts.on('-hf', '--hotspot-files', 'Print the found hotspot files (big files touched by many) [default: false]') do
25
+ opts.on('--hotspot-files', 'Print the found hotspot files (big files touched by many) [default: false]') do
26
26
  options[:hotspot_files] = true
27
27
  end
28
28
 
29
- opts.on('-ec', '--excluded-contributors STRING', 'Comma-delimited list of excluded contributors [example: WEB,RAILS,MOBILE]') do |exclusions|
29
+ opts.on('--excluded-contributors STRING', 'Comma-delimited list of excluded contributors [example: WEB,RAILS,MOBILE]') do |exclusions|
30
30
  options[:exclusions] = exclusions
31
31
  end
32
32
 
33
- opts.on('-ef', '--excluded-files STRING', 'Comma-delimited list of excluded files [example: ViewController,AppDelegate.swift]') do |excluded_files|
33
+ opts.on('--excluded-files STRING', 'Comma-delimited list of excluded files [example: ViewController,AppDelegate.swift]') do |excluded_files|
34
34
  options[:excluded_files] = excluded_files
35
35
  end
36
36
 
37
- opts.on('-s', '--steps STRING', 'Number of steps the script will go into the past [default: 1]') do |steps|
37
+ opts.on('--steps STRING', 'Number of steps the script will go into the past [default: 1]') do |steps|
38
38
  options[:steps] = steps
39
39
  end
40
40
 
41
- opts.on('-d', '--duration-in-days STRING',
41
+ opts.on('--duration-in-days STRING',
42
42
  'Number of days to aggregate the changes for [default: 30]') do |duration_in_days|
43
43
  options[:duration_in_days] = duration_in_days
44
44
  end
45
45
 
46
- opts.on('-p', '--path STRING', 'Path to the directory or file to calculate the ownership [default: "."]') do |path|
46
+ opts.on('--path STRING', 'Path to the directory or file to calculate the ownership [default: "."]') do |path|
47
47
  options[:path] = path
48
48
  end
49
49
 
50
- opts.on('-reg', '--team-regex STRING', 'Regex that will identify the team name [default: "[A-Za-z]+"]') do |team_regex|
50
+ opts.on('--team-regex STRING', 'Regex that will identify the team name [default: "[A-Za-z]+"]') do |team_regex|
51
51
  options[:team_regex] = team_regex
52
52
  end
53
53
 
54
- opts.on('-t', '--top-contributing-team STRING', 'Limit of top contributed to the directory teams in codeownership data [default: 5]') do |top_contributing_team|
54
+ opts.on('--top-contributing-team STRING', 'Limit of top contributed to the directory teams in codeownership data [default: 5]') do |top_contributing_team|
55
55
  options[:top_contributing_team] = top_contributing_team
56
56
  end
57
57
 
58
- opts.on('-files', '--top-touched-files STRING', 'Limit of top touched files by individual contributors in codeownership data [default: 5]') do |top_touched_files|
58
+ opts.on('--top-touched-files STRING', 'Limit of top touched files by individual contributors in codeownership data [default: 5]') do |top_touched_files|
59
59
  options[:top_touched_files] = top_touched_files
60
60
  end
61
61
 
62
- opts.on('-cp', '--codeowners-path STRING', 'Path to CODEOWNERS file [default: .github/CODEOWNERS]') do |codeowners_path|
62
+ opts.on('--codeowners-path STRING', 'Path to CODEOWNERS file [default: .github/CODEOWNERS]') do |codeowners_path|
63
63
  options[:codeowners_path] = codeowners_path
64
64
  end
65
65
 
66
- opts.on('-s', '--big-file-size STRING', 'The amount of lines in the file to be considered big [default: 250]') do |big_file_size|
66
+ opts.on('--big-file-size STRING', 'The amount of lines in the file to be considered big [default: 250]') do |big_file_size|
67
67
  options[:big_file_size] = big_file_size
68
68
  end
69
69
 
70
- opts.on('-b', '--default-branch STRING', 'The default branch to pull and run metrics for [default: master]') do |default_branch|
70
+ opts.on('--default-branch STRING', 'The default branch to pull and run metrics for [default: master]') do |default_branch|
71
71
  options[:default_branch] = default_branch
72
72
  end
73
73
 
74
- opts.on('-ext', '--code-extensions STRING', 'The file extensions that consider to be code [default: ".kt, .swift"]') do |code_extension|
74
+ opts.on('--code-extensions STRING', 'The file extensions that consider to be code [default: ".kt, .swift"]') do |code_extension|
75
75
  options[:code_extension] = code_extension
76
76
  end
77
77
 
@@ -145,6 +145,7 @@ def find_owners(file_path, codeowners)
145
145
  end
146
146
 
147
147
  def count_big_files(directory_path, size: BIG_FILE_SIZE)
148
+ size = size.to_i
148
149
  # Get a list of all files in the specified directory
149
150
  files = Dir.glob(File.join(directory_path, '**', '*')).select { |file| File.file?(file) }
150
151
 
@@ -166,12 +167,33 @@ def count_big_files(directory_path, size: BIG_FILE_SIZE)
166
167
  end
167
168
  end
168
169
 
169
- puts " Total number of files longer than #{size} lines: #{count}"
170
+ puts " Total number of code files longer than #{size} lines: #{count}"
171
+ end
172
+
173
+ def count_hotspot_lines(files)
174
+ code_files = files.select {|f|
175
+ extension = File.extname(f)
176
+ valid_extensions = ['.swift', '.kt']
177
+ valid_extensions.include?(extension)
178
+ }
179
+
180
+ # Initialize a counter for files that meet the criteria
181
+ count = 0
182
+
183
+ # Iterate through each file and check the line count
184
+ code_files.each do |file|
185
+ lines_count = File.foreach(file).reject { |line| line.match(/^\s*(\/\/|\/\*.*\*\/|\s*$)/) }.count
186
+
187
+ count += lines_count
188
+ end
189
+
190
+ puts " Total lines of hotspot code: #{count}"
170
191
  end
171
192
 
172
193
  def contribution_message(directory_path:, duration_in_days:, begin_time:, debug: nil, steps: nil)
173
194
  duration_in_days = duration_in_days.to_i
174
195
  all_teams = []
196
+ teams_count = 0
175
197
  files_changed_by_many_teams = 0
176
198
  total_changes = 0
177
199
  start_date = begin_time.to_time.to_i - duration_in_days * 86_400
@@ -212,6 +234,7 @@ def contribution_message(directory_path:, duration_in_days:, begin_time:, debug:
212
234
  if teams.count > 1
213
235
  files_changed_by_many_teams += 1
214
236
  file_team_map.merge!("#{file}" => [teams, commit_count])
237
+ teams_count += teams.count
215
238
  end
216
239
 
217
240
  puts "\n#{filename} [#{commit_count}]:#{teams}\n" if debug
@@ -224,7 +247,14 @@ def contribution_message(directory_path:, duration_in_days:, begin_time:, debug:
224
247
  churn_count = file_team_map.values.map { |value| value[1] }.sum
225
248
  hotspot_changes_percentage = (churn_count.to_f / total_changes.to_f)*100
226
249
 
227
- puts "Timeframe: #{(begin_time - duration_in_days).strftime('%Y-%m-%d')} to #{begin_time.strftime('%Y-%m-%d')}\n Code files with a single contributor: #{(100 - ((files_changed_by_many_teams.to_f / code_files_with_changes.count.to_f) * 100)).round(2)}%\n Hotspot code changes: #{churn_count} (#{hotspot_changes_percentage.round(2)}%)\n Amount of code changes: #{total_changes}\n Total files changed: #{code_files_with_changes.count}\n Total files in the folder: #{file_count}\n Contributors: #{contributors}\n"
250
+ puts "Timeframe: #{(begin_time - duration_in_days).strftime('%Y-%m-%d')} to #{begin_time.strftime('%Y-%m-%d')}"
251
+ puts " Code files with a single contributor: #{(100 - ((files_changed_by_many_teams.to_f / code_files_with_changes.count.to_f) * 100)).round(2)}%"
252
+ puts " Hotspot code changes: #{churn_count} (#{hotspot_changes_percentage.round(2)}%)"
253
+ puts " Total occurrences of cross-squad dependencies over same files: #{teams_count}"
254
+ puts " Amount of code changes: #{total_changes}"
255
+ puts " Total files changed: #{code_files_with_changes.count}"
256
+ puts " Total files in the folder: #{file_count}"
257
+ puts " Contributors: #{contributors}"
228
258
 
229
259
  # Filter files based on extension and size
230
260
  filtered_files = file_team_map.select do |file_path|
@@ -236,6 +266,7 @@ def contribution_message(directory_path:, duration_in_days:, begin_time:, debug:
236
266
 
237
267
  filtered_top_touched_files = filtered_files.sort_by { |element, count| [-count.last, element] }
238
268
  count_big_files(directory_path)
269
+ count_hotspot_lines(filtered_files.keys)
239
270
  puts " Total files longer than #{BIG_FILE_SIZE} lines with multiple contributors: #{filtered_top_touched_files.count}\n"
240
271
  if HOTSPOT
241
272
  filtered_top_touched_files.each do |line|
@@ -313,7 +344,7 @@ unless CI
313
344
  end
314
345
 
315
346
  system("git checkout #{DEFAULT_BRANCH}", [ :out ] => File::NULL)
316
- system("git pull", [ :out ] => File::NULL)
347
+ system("git pull", [ :out, :err ] => File::NULL)
317
348
 
318
349
  contribution_message(duration_in_days: options[:duration_in_days] || 30, directory_path: REPO_PATH,
319
350
  begin_time: DateTime.now, steps: options[:steps].to_i, debug: options[:debug])
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GitOwnershipInsights
4
- VERSION = '1.0.3'
4
+ VERSION = '1.0.5'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git_ownership_insights
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serghei Moret