github_repo_statistics 2.2.15 → 2.2.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/bin/release_merge_report +57 -0
- data/lib/github_repo_statistics/force_merge_report.rb +1 -0
- data/lib/github_repo_statistics/github_repo_statistics.rb +24 -9
- data/lib/github_repo_statistics/release_merge_report.rb +112 -0
- data/lib/github_repo_statistics/review_report.rb +1 -0
- data/lib/github_repo_statistics/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8169d892f1d72c50d184868f6857ca0025b01cd15331e686f7df54b6f202aee
|
4
|
+
data.tar.gz: 9e459684119ab981629054fe8f4c3896f9f4d3dad3901af315ba2bcb4582191c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1564877229312ef1fee2c1fac355fe4e1c6df216523e368665c626f768e5215acf02a934a3785dce7971862d803f5835dc3d0fdc58e670d004eea109d27e9c30
|
7
|
+
data.tar.gz: 40949fa763572d6c16a12af50019a7c4eb29d4a273808c114bbf451abf5d4c61b2e64df488202bb191069cb18ce941665d3d697fcae60e83070e3f075433298c
|
data/Gemfile.lock
CHANGED
@@ -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
|
@@ -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 =
|
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
|
-
|
319
|
-
|
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
|
-
|
324
|
-
|
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
|
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 -
|
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 -=
|
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"
|
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.
|
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-
|
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
|