github_repo_statistics 2.2.15 → 2.2.16

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: d542f1342809e591c429c25f03127747b74b9966915cfd78242d4e8a12576ce1
4
- data.tar.gz: e6b1d1380abf5bf896c2e4ebdfb29ac595a0b4111db526ad2e50b3955a9d35ab
3
+ metadata.gz: b4d3e1e79a329a849e3dc178cd55be3d0b420738ca81f04e8ac54775f1c92e4c
4
+ data.tar.gz: e609fbeea3149601a2a14d823d4e5fd47b4f09626b651bab2e419261482018f7
5
5
  SHA512:
6
- metadata.gz: a5a03550f06f6a90b3c9a0912e068bfb446599b56a84190b4ee35b402421fdeefabffbe2f462406973d67bd4b76128493ed6bd56b6614405e3c0c24da113f2b9
7
- data.tar.gz: 9e996b48a2b6269fe884853fe64fbaa4edfbf13f9784b17528d1e10d54e517431b36267c5be99e4224d3e82b981f6936d3f0e7f1287048bcee042eb75a88c48b
6
+ metadata.gz: ba6a269abb17d017b184baf8f68df4f7ed749d9dca1d7a361baa2a1bba3e17de6255cd10379177089e3ac2f2d660ad01ce7862b37f2c67b02a268cac17e8625f
7
+ data.tar.gz: 5ab0ae384a28af25dde05d51853969213fa941f7f4add7edbe7718d71d4c03f08955c316c8ebe753be77c72756aaec6775c67187724eb72d4055664575ba1bf1
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,30 @@ 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
 
322
329
  if FILE_OUTPUT
323
- File.open('hotspot.txt', 'w') do |f|
324
- f.puts hotspot_output
330
+ CSV.open('hotspot.csv', 'w') do |csv|
331
+ csv << ['File', 'Contributors', 'Lines', 'Commits', 'Owner']
332
+ hotspot_output.each do |row|
333
+ csv << row
334
+ end
325
335
  end
326
336
  else
327
- puts hotspot_output
337
+ puts "\n *Hotspot files(#{filtered_top_touched_files.count}):*\n"
338
+ hotspot_output.each do |row|
339
+ puts " #{row[0]} Contributors: #{row[1]} Lines: #{row[2]} Commits: #{row[3]} Owner: #{row[4]}"
340
+ end
328
341
  end
329
342
  end
330
343
 
@@ -334,9 +347,9 @@ class GithubRepoStatistics
334
347
 
335
348
  return unless @steps.positive?
336
349
 
337
- system("git checkout `git rev-list -1 --before='#{(@begin_time - 7).strftime('%B %d %Y')}' HEAD`",
350
+ system("git checkout `git rev-list -1 --before='#{(@begin_time - duration_in_days).strftime('%B %d %Y')}' HEAD`",
338
351
  %i[out err] => File::NULL)
339
- @begin_time -= 7
352
+ @begin_time -= duration_in_days
340
353
  contribution_message
341
354
  end
342
355
  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.16'
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.16
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