dev_metrics 0.1.0 → 0.1.2

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: 8f7562e3289d9e63952c28d3204862e9096ab36655b86c3feb59d150c6305451
4
- data.tar.gz: '0329ed36f933b308443a701ef1407d136f090ffabc5ca8a87af65f94355ce05c'
3
+ metadata.gz: 61eeda6933db54b48b7f7ca3941b035da3d04f9f9a8e6d414b8ef9db87a265ea
4
+ data.tar.gz: c2477155037f8f078dc7ffcc044c7cba1767915a0334434af365ddf967fcca06
5
5
  SHA512:
6
- metadata.gz: 345d1aa1578ad62febbd626899f13e3fe66ac66b9d879d3bc71514f399bbb9239b5e8202b7d30abb0142686efe5f25a0ae5917c9d805920ec92c6793820e5cfa
7
- data.tar.gz: b747b37e4fdac8801d4f6758e5ccadeced27c810bda5e643fd0e238af6ed9880bc1e02129446d545a88e507c4e0ab8238e2e735007e5ded3d34683f0e642e511
6
+ metadata.gz: 3ed77728ffae77e7e4ff2f84affc023902fabbd2c9cd2adce81cc3b40b88eb02d97f1c6ced8e7bf7323452234274b29229f3ea775618ab3324ecc3752f4130e3
7
+ data.tar.gz: b7d5c47d5d486014d03ab9829b4f325377aa0f5c07c7e64b5f1692d0d308333352f45ea9eaf3b89f6120a374be8ddfec7fb36d7054b037887ee1d8f9c74a5505
@@ -3,7 +3,7 @@ require 'uri'
3
3
  require 'date'
4
4
  require 'json'
5
5
  require 'time'
6
- require 'pry'
6
+ require_relative 'query_builder'
7
7
 
8
8
  module DevMetrics
9
9
  class Client
@@ -14,14 +14,22 @@ module DevMetrics
14
14
  @repo_name = config.repo_name
15
15
  @bot_accounts = config.bot_accounts || []
16
16
  @access_token = config.access_token || ENV.fetch('GITHUB_ACCESS_TOKEN', nil)
17
+ @fix_branch_names = config.fix_branch_names || %w(hotfix fix rollback)
17
18
  end
18
19
 
19
20
  def process(period: Date.today)
20
21
  uri = URI.parse(GITHUB_GRAPHQL_API)
21
- request = build_request(uri, period)
22
- response = execute_request(uri, request)
22
+ builder = DevMetrics::QueryBuilder.new(@repo_name)
23
+
24
+ auth_request = build_request(uri, builder.access_auth_check)
25
+ auth_response = execute_request(uri, auth_request)
26
+ check_auth_errors!(auth_response)
27
+
28
+ pr_request = build_request(uri, builder.pull_requests_for(period))
29
+ pr_response = execute_request(uri, pr_request)
30
+
31
+ pr_data = parse_response(pr_response)
23
32
 
24
- pr_data = parse_response(response)
25
33
  filtered_prs = exclude_bots(pr_data)
26
34
  correction_pr_count = count_correction_prs(filtered_prs)
27
35
 
@@ -31,11 +39,10 @@ module DevMetrics
31
39
 
32
40
  private
33
41
 
34
- def build_request(uri, period)
42
+ def build_request(uri, body)
35
43
  request = Net::HTTP::Post.new(uri)
36
- request["Authorization"] = "Bearer #{@access_token}"
37
- request.body = graphql_query(period)
38
-
44
+ request['Authorization'] = "Bearer #{@access_token}"
45
+ request.body = body
39
46
  request
40
47
  end
41
48
 
@@ -44,12 +51,21 @@ module DevMetrics
44
51
  Net::HTTP.start(uri.hostname, uri.port, options) { |http| http.request(request) }
45
52
  end
46
53
 
54
+ def check_auth_errors!(response)
55
+ if response.code.to_i == 403 || response.body.include?('FORBIDDEN')
56
+ raise "Access denied: ensure the access token has permission to access #{@repo_name}"
57
+ end
58
+ end
59
+
47
60
  def parse_response(response)
48
61
  unless response.is_a?(Net::HTTPSuccess)
49
62
  raise "Failed to fetch data: #{response.message} (#{response.code})"
50
63
  end
51
64
 
52
- JSON.parse(response.body).dig('data', 'search', 'edges')
65
+ data = JSON.parse(response.body)
66
+ raise "GraphQL error: #{data['errors']}" if data['errors']
67
+
68
+ data.dig('data', 'search', 'edges') || []
53
69
  end
54
70
 
55
71
  def exclude_bots(prs)
@@ -58,7 +74,7 @@ module DevMetrics
58
74
  end
59
75
 
60
76
  def count_correction_prs(prs)
61
- prs.count { |pr| pr.dig('node', 'headRefName')&.match?(/^hotfix|fix|rollback/) }
77
+ prs.count { |pr| pr.dig('node', 'headRefName')&.match?(/^#{@fix_branch_names.join('|')}/) }
62
78
  end
63
79
 
64
80
  def calculate_lead_time(prs)
@@ -81,30 +97,6 @@ module DevMetrics
81
97
  Time.at(remaining).utc.strftime("#{days}d %H:%M:%S")
82
98
  end
83
99
 
84
- def graphql_query(period)
85
- query_string = <<-GRAPHQL
86
- {
87
- search(query: "repo:#{@repo_name} is:pr merged:#{period}", type: ISSUE, first: 100) {
88
- edges {
89
- node {
90
- ... on PullRequest {
91
- url
92
- title
93
- author {
94
- login
95
- }
96
- mergedAt
97
- headRefName
98
- publishedAt
99
- }
100
- }
101
- }
102
- }
103
- }
104
- GRAPHQL
105
- { "query" => query_string.strip }.to_json
106
- end
107
-
108
100
  def output_metrics(period, prs, correction_pr_count)
109
101
  formatted_data = format_data(period, prs, correction_pr_count)
110
102
 
@@ -8,12 +8,16 @@ module DevMetrics
8
8
  def format_data(period, prs, correction_pr_count)
9
9
  output = ""
10
10
  output << "| #{period} | #{prs.count} | #{correction_pr_count} | "
11
- output << "#{((correction_pr_count.to_f / prs.count) * 100).round(2)}% | "
11
+ output << "#{correction_calc(correction_pr_count, prs)}% | "
12
12
  output << "#{calculate_lead_time(prs)} | "
13
13
  output << "[PRs for #{period}](https://github.com/#{@repo_name}/pulls?q=is%3Apr+merged%3A#{period}) |\n"
14
14
  output
15
15
  end
16
16
 
17
+ def correction_calc(correction_pr_count, prs)
18
+ return "-" if prs.empty?
19
+ ((correction_pr_count.to_f / prs.count) * 100).round(2)
20
+ end
17
21
  def output_filename
18
22
  "metrics_report.md"
19
23
  end
@@ -0,0 +1,44 @@
1
+ module DevMetrics
2
+ class QueryBuilder
3
+
4
+ def initialize(repo)
5
+ @repo = repo
6
+ end
7
+ def access_auth_check
8
+ to_body <<~GRAPHQL
9
+ {
10
+ repository(owner: "#{@repo.split('/')[0]}", name: "#{@repo.split('/')[1]}"){
11
+ id
12
+ }
13
+ }
14
+ GRAPHQL
15
+ end
16
+
17
+ def pull_requests_for(period)
18
+ to_body <<~GRAPHQL
19
+ {
20
+ search(query: "repo:#{@repo} is:pr merged:#{period}", type: ISSUE, first: 100) {
21
+ edges {
22
+ node {
23
+ ... on PullRequest {
24
+ url
25
+ title
26
+ author { login }
27
+ mergedAt
28
+ headRefName
29
+ publishedAt
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ GRAPHQL
36
+ end
37
+
38
+ private
39
+
40
+ def to_body(query_string)
41
+ { "query" => query_string.strip }.to_json
42
+ end
43
+ end
44
+ end
data/lib/dev_metrics.rb CHANGED
@@ -2,12 +2,13 @@ require_relative 'dev_metrics/markdown'
2
2
 
3
3
  module DevMetrics
4
4
  class Config
5
- attr_accessor :access_token, :repo_name, :bot_accounts
5
+ attr_accessor :access_token, :repo_name, :bot_accounts, :fix_branch_names
6
6
 
7
7
  def initialize
8
8
  @access_token = nil
9
9
  @repo_name = nil
10
10
  @bot_accounts = nil
11
+ @fix_branch_names = nil
11
12
  end
12
13
  end
13
14
 
@@ -21,9 +22,8 @@ module DevMetrics
21
22
  yield(configuration)
22
23
  end
23
24
 
24
- def self.run(format, date)
25
- # 設定を使用してMarkdownクラスを呼び出す
26
- markdown_processor = format.new(@configuration)
27
- markdown_processor.process(period: date)
25
+ def self.run(period:, format:)
26
+ client = format.new(@configuration)
27
+ client.process(period: period)
28
28
  end
29
29
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dev_metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sean2121
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-04 00:00:00.000000000 Z
11
+ date: 2025-04-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description:
14
- email:
13
+ description:
14
+ email:
15
15
  executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
@@ -19,11 +19,12 @@ files:
19
19
  - lib/dev_metrics.rb
20
20
  - lib/dev_metrics/client.rb
21
21
  - lib/dev_metrics/markdown.rb
22
- homepage:
22
+ - lib/dev_metrics/query_builder.rb
23
+ homepage:
23
24
  licenses:
24
25
  - MIT
25
26
  metadata: {}
26
- post_install_message:
27
+ post_install_message:
27
28
  rdoc_options: []
28
29
  require_paths:
29
30
  - lib
@@ -39,7 +40,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
39
40
  version: '0'
40
41
  requirements: []
41
42
  rubygems_version: 3.2.33
42
- signing_key:
43
+ signing_key:
43
44
  specification_version: 4
44
45
  summary: A RubyGem for tracking and analyzing development metrics from various repositories.
45
46
  test_files: []