github_repo_statistics 2.2.15 → 2.2.17

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d542f1342809e591c429c25f03127747b74b9966915cfd78242d4e8a12576ce1
4
- data.tar.gz: e6b1d1380abf5bf896c2e4ebdfb29ac595a0b4111db526ad2e50b3955a9d35ab
3
+ metadata.gz: a8169d892f1d72c50d184868f6857ca0025b01cd15331e686f7df54b6f202aee
4
+ data.tar.gz: 9e459684119ab981629054fe8f4c3896f9f4d3dad3901af315ba2bcb4582191c
5
5
  SHA512:
6
- metadata.gz: a5a03550f06f6a90b3c9a0912e068bfb446599b56a84190b4ee35b402421fdeefabffbe2f462406973d67bd4b76128493ed6bd56b6614405e3c0c24da113f2b9
7
- data.tar.gz: 9e996b48a2b6269fe884853fe64fbaa4edfbf13f9784b17528d1e10d54e517431b36267c5be99e4224d3e82b981f6936d3f0e7f1287048bcee042eb75a88c48b
6
+ metadata.gz: 1564877229312ef1fee2c1fac355fe4e1c6df216523e368665c626f768e5215acf02a934a3785dce7971862d803f5835dc3d0fdc58e670d004eea109d27e9c30
7
+ data.tar.gz: 40949fa763572d6c16a12af50019a7c4eb29d4a273808c114bbf451abf5d4c61b2e64df488202bb191069cb18ce941665d3d697fcae60e83070e3f075433298c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- github_repo_statistics (2.2.13)
4
+ github_repo_statistics (2.2.15)
5
5
  date
6
6
  faraday-retry
7
7
  google-cloud-bigquery
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'date'
5
+ require 'optparse'
6
+ require 'pry'
7
+ require_relative '../lib/github_repo_statistics/version'
8
+ require_relative '../lib/github_repo_statistics/release_merge_report'
9
+
10
+
11
+ options = {}
12
+ OptionParser.new do |opts|
13
+ opts.banner = 'Usage: github_repo_statistics [options]'
14
+
15
+ opts.on('--duration-in-days STRING',
16
+ 'Number of days to aggregate the changes for [default: 90]') do |duration_in_days|
17
+ options[:duration_in_days] = duration_in_days.to_i
18
+ end
19
+
20
+ opts.on('--default-branch STRING',
21
+ 'The default branch to pull and run metrics for [default: master]') do |default_branch|
22
+ options[:default_branch] = default_branch
23
+ end
24
+
25
+ opts.on('--github-token STRING',
26
+ 'GitHub API token [default: ""]') do |github_token|
27
+ options[:github_token] = github_token
28
+ end
29
+
30
+ opts.on('--github-repo STRING',
31
+ 'GitHub repository name and owner (e.g. octokit/octokit) [default: ""]') do |github_repo|
32
+ options[:github_repo] = github_repo
33
+ end
34
+
35
+ opts.on('-v', '--version', 'Display the version of the gem') do
36
+ puts "github_repo_statistics version #{GithubRepoStatistics::VERSION}"
37
+ exit
38
+ end
39
+
40
+ opts.on('-h', '--help', 'Display this help message') do
41
+ puts opts
42
+ puts <<~EXAMPLES
43
+
44
+ Examples:
45
+ review_report --github-token ghp_bKasj29ndkfdksf3rjt2ngi43j --github-repo octokit/octokit
46
+ EXAMPLES
47
+ exit
48
+ end
49
+ end.parse!
50
+
51
+ DEFAULT_BRANCH = options[:default_branch] || 'master'
52
+
53
+ raise 'Please provide GitHub token using --github-token flag' if options[:github_token].nil?
54
+ raise 'Please provide GitHub repo name using --github-repo flag' if options[:github_repo].nil?
55
+ raise 'Please provide default GitHub branch using --default-branch flag' if DEFAULT_BRANCH.nil?
56
+
57
+ ReleaseMergeReport.new(token: options[:github_token], repo: options[:github_repo], branch_prefix: "release/").report
@@ -91,6 +91,7 @@ class ForceMergeReport
91
91
  puts " - #{workflow}: #{count}"
92
92
  end
93
93
 
94
+ # ENV['BQ_CREDENTIALS'] = `cat /Users/serghei.moret/.config/gcloud/application_default_credentials.json`
94
95
 
95
96
  if ENV['BQ_CREDENTIALS']
96
97
  require "google/cloud/bigquery"
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'pry'
4
4
  require 'date'
5
+ require 'csv'
5
6
 
6
7
  class GithubRepoStatistics
7
8
  def initialize(directory_path:, duration_in_days:, begin_time:, debug: nil, steps: 1)
@@ -145,6 +146,10 @@ class GithubRepoStatistics
145
146
  count
146
147
  end
147
148
 
149
+ def count_lines_of_code(file)
150
+ File.foreach(file).reject { |line| line.match(%r{^\s*(//|/\*.*\*/|\s*$)}) }.count
151
+ end
152
+
148
153
  def filter_existing_code_files(files)
149
154
  files.select do |f|
150
155
  next unless File.exist?(f)
@@ -243,6 +248,7 @@ class GithubRepoStatistics
243
248
  hotspot_lines = count_hotspot_lines(filtered_files.keys)
244
249
  big_files_count = count_big_files(@directory_path)
245
250
 
251
+ # ENV['BQ_CREDENTIALS'] = `cat /Users/serghei.moret/.config/gcloud/application_default_credentials.json`
246
252
 
247
253
  if ENV['BQ_CREDENTIALS']
248
254
  require "google/cloud/bigquery"
@@ -308,23 +314,32 @@ class GithubRepoStatistics
308
314
  puts " *Contributors:* #{contributors}"
309
315
 
310
316
  if HOTSPOT
311
- hotspot_output = "\n *Hotspot files(#{filtered_top_touched_files.count}):*\n"
317
+ hotspot_output = []
312
318
 
313
319
  filtered_top_touched_files.each do |line|
314
- hotspot_output += "\n"
315
320
  file = line.first
316
321
  contributors = line.last.first
322
+ lines_of_code = count_lines_of_code(file)
317
323
  commits = line.last.last
318
- hotspot_output += " #{file.gsub(@directory_path,
319
- '')} Contributors: #{contributors} Commits: #{commits} Owner: #{find_owner(file:)}\n"
324
+ owner = find_owner(file:)
325
+
326
+ hotspot_output << [file.gsub(@directory_path, ''), contributors, lines_of_code, commits, owner]
320
327
  end
321
328
 
329
+ hotspot_output.sort_by! { |row| row[2] }
330
+
322
331
  if FILE_OUTPUT
323
- File.open('hotspot.txt', 'w') do |f|
324
- f.puts hotspot_output
332
+ CSV.open('hotspot.csv', 'w') do |csv|
333
+ csv << ['File', 'Contributors', 'Lines', 'Commits', 'Owner']
334
+ hotspot_output.each do |row|
335
+ csv << row
336
+ end
325
337
  end
326
338
  else
327
- puts hotspot_output
339
+ puts "\n *Hotspot files(#{filtered_top_touched_files.count}):*\n"
340
+ hotspot_output.each do |row|
341
+ puts " #{row[0]} Contributors: #{row[1]} Lines: #{row[2]} Commits: #{row[3]} Owner: #{row[4]}"
342
+ end
328
343
  end
329
344
  end
330
345
 
@@ -334,9 +349,9 @@ class GithubRepoStatistics
334
349
 
335
350
  return unless @steps.positive?
336
351
 
337
- system("git checkout `git rev-list -1 --before='#{(@begin_time - 7).strftime('%B %d %Y')}' HEAD`",
352
+ system("git checkout `git rev-list -1 --before='#{(@begin_time - duration_in_days).strftime('%B %d %Y')}' HEAD`",
338
353
  %i[out err] => File::NULL)
339
- @begin_time -= 7
354
+ @begin_time -= duration_in_days
340
355
  contribution_message
341
356
  end
342
357
  end
@@ -0,0 +1,112 @@
1
+ require 'octokit'
2
+ require 'json'
3
+ require 'google/cloud/bigquery'
4
+
5
+ class ReleaseMergeReport
6
+ def initialize(token:, repo:, branch_prefix:)
7
+ @token = token
8
+ @repo = repo
9
+ @branch_prefix = branch_prefix
10
+ end
11
+
12
+ def report
13
+ branch_counts = count_merged_pull_requests_per_branch
14
+ grouped_branch_counts = group_branch_counts(branch_counts)
15
+ require 'pry'
16
+ binding.pry
17
+
18
+ # Print the grouped branch counts
19
+ puts 'Branches with Merged Pull Requests:'
20
+ grouped_branch_counts.each do |branch, count|
21
+ puts "#{branch}: #{count}"
22
+ end
23
+
24
+ ENV['BQ_CREDENTIALS'] = `cat /Users/serghei.moret/.config/gcloud/application_default_credentials.json`
25
+
26
+ export_to_bigquery(grouped_branch_counts) if ENV['BQ_CREDENTIALS']
27
+
28
+ grouped_branch_counts
29
+ end
30
+
31
+ private
32
+
33
+ def count_merged_pull_requests_per_branch
34
+ client = Octokit::Client.new(access_token: @token)
35
+ client.auto_paginate = true
36
+
37
+ tags = client.tags(@repo)
38
+ branch_counts = Hash.new(0)
39
+
40
+ tags.each do |tag|
41
+ next if !tag.name.match?(/^(v23|v24)\./) && !tag.name.match?(/^(23|24)\./)
42
+
43
+ # Extract release version from the tag name
44
+ release_version = tag.name.gsub('v', '')
45
+
46
+ # Construct branch name with the specified prefix
47
+ branch_name = "#{@branch_prefix}#{release_version}"
48
+
49
+ # Count merged pull requests associated with the branch
50
+ pull_requests = client.pull_requests(@repo, state: 'closed', sort: 'updated', direction: 'desc', base: branch_name)
51
+ .select { |pr| pr.merged_at }
52
+
53
+ branch_counts[branch_name] = pull_requests.size
54
+ end
55
+
56
+ branch_counts
57
+ end
58
+
59
+ def group_branch_counts(branch_counts)
60
+ patch_counts = Hash.new(0)
61
+ hotfix_counts = Hash.new { |hash, key| hash[key] = Hash.new(0) }
62
+
63
+ branch_counts.each do |branch, count|
64
+ major_minor_version, patch_version = branch.match(/^#{@branch_prefix}(\d+\.\d+)(?:\.(\d+))?/)&.captures
65
+
66
+ if patch_version.nil?
67
+ # Branch is a patch version
68
+ patch_counts[major_minor_version] += count
69
+ elsif count > 0
70
+ # Branch is a hotfix version
71
+ hotfix_counts[major_minor_version][patch_version] += count
72
+ end
73
+ end
74
+
75
+ # Sum up the counts for hotfix versions within the same major and minor version
76
+ hotfix_counts.each do |major_minor_version, hotfixes|
77
+ hotfix_counts[major_minor_version] = hotfixes.values.sum
78
+ end
79
+
80
+ { patch_versions: patch_counts, hotfix_versions: hotfix_counts }
81
+ end
82
+
83
+ def export_to_bigquery(branch_counts)
84
+ require "google/cloud/bigquery"
85
+ require "json"
86
+ creds = JSON.parse(ENV['BQ_CREDENTIALS'])
87
+ bigquery = Google::Cloud::Bigquery.new(
88
+ project_id: "hellofresh-android",
89
+ credentials: creds
90
+ )
91
+ dataset = bigquery.dataset "github_data"
92
+
93
+ date = DateTime.now
94
+
95
+ branch_counts.each do |branch, count|
96
+ query = <<~SQL
97
+ MERGE INTO release_merges AS target
98
+ USING (SELECT '#{branch}' AS release, '#{@repo}' AS platform) AS source
99
+ ON target.release = source.release AND target.platform = source.platform
100
+ WHEN MATCHED THEN
101
+ UPDATE SET
102
+ target.merge_count = #{count},
103
+ target.timestamp = '#{date}'
104
+ WHEN NOT MATCHED THEN
105
+ INSERT (release, merge_count, platform, timestamp)
106
+ VALUES ('#{branch}', #{count}, '#{@repo}', '#{date}');
107
+ SQL
108
+ date -= 7
109
+ dataset.query(query)
110
+ end
111
+ end
112
+ end
@@ -87,6 +87,7 @@ class ReviewReport
87
87
  puts " Reviews with comments: #{reviews_with_comments}"
88
88
  puts " Change requested reviews: #{change_requested_reviews}"
89
89
 
90
+ # ENV['BQ_CREDENTIALS'] = `cat /Users/serghei.moret/.config/gcloud/application_default_credentials.json`
90
91
 
91
92
  if ENV['BQ_CREDENTIALS']
92
93
  require "google/cloud/bigquery"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GithubRepoStatistics
4
- VERSION = '2.2.15'
4
+ VERSION = '2.2.17'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github_repo_statistics
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.15
4
+ version: 2.2.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serghei Moret
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-19 00:00:00.000000000 Z
11
+ date: 2024-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: date
@@ -87,6 +87,7 @@ executables:
87
87
  - console
88
88
  - force_merge_report
89
89
  - github_repo_statistics
90
+ - release_merge_report
90
91
  - review_report
91
92
  - setup
92
93
  extensions: []
@@ -108,12 +109,14 @@ files:
108
109
  - bin/console
109
110
  - bin/force_merge_report
110
111
  - bin/github_repo_statistics
112
+ - bin/release_merge_report
111
113
  - bin/review_report
112
114
  - bin/setup
113
115
  - github_repo_statistics.gemspec
114
116
  - lib/github_repo_statistics.rb
115
117
  - lib/github_repo_statistics/force_merge_report.rb
116
118
  - lib/github_repo_statistics/github_repo_statistics.rb
119
+ - lib/github_repo_statistics/release_merge_report.rb
117
120
  - lib/github_repo_statistics/review_report.rb
118
121
  - lib/github_repo_statistics/version.rb
119
122
  - sig/github_repo_statistics.rbs