Class: GithubGateway

Inherits:
Object
  • Object
show all
Defined in:
lib/jirametrics/github_gateway.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repo:, project_keys:, file_system:, raw_pr_cache: {}) ⇒ GithubGateway

Returns a new instance of GithubGateway.



9
10
11
12
13
14
15
# File 'lib/jirametrics/github_gateway.rb', line 9

def initialize repo:, project_keys:, file_system:, raw_pr_cache: {}
  @repo = repo
  @project_keys = project_keys
  @file_system = file_system
  @raw_pr_cache = raw_pr_cache
  @issue_key_pattern = build_issue_key_pattern
end

Instance Attribute Details

#repoObject (readonly)

Returns the value of attribute repo.



7
8
9
# File 'lib/jirametrics/github_gateway.rb', line 7

def repo
  @repo
end

Instance Method Details

#build_pr_data(raw_pr) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/jirametrics/github_gateway.rb', line 36

def build_pr_data raw_pr
  issue_keys = extract_issue_keys(raw_pr)
  return nil if issue_keys.empty?

  PullRequest.new(raw: {
    'number'     => raw_pr['number'],
    'repo'       => @repo,
    'url'        => raw_pr['url'],
    'title'      => raw_pr['title'],
    'branch'     => raw_pr['headRefName'],
    'opened_at'  => raw_pr['createdAt'],
    'closed_at'  => raw_pr['closedAt'],
    'merged_at'  => raw_pr['mergedAt'],
    'state'      => raw_pr['state'],
    'issue_keys'    => issue_keys,
    'reviews'       => extract_reviews(raw_pr['reviews'] || []),
    'additions'     => raw_pr['additions'],
    'deletions'     => raw_pr['deletions'],
    'changed_files' => raw_pr['changedFiles']
  })
end

#extract_issue_keys(raw_pr) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/jirametrics/github_gateway.rb', line 58

def extract_issue_keys raw_pr
  return [] if @issue_key_pattern.nil?

  sources = [
    raw_pr['headRefName'],
    raw_pr['title'],
    raw_pr['body']
  ]

  keys = sources.compact.flat_map { |s| s.scan(@issue_key_pattern) }.uniq
  return keys unless keys.empty?

  commit_messages_for(raw_pr['number']).flat_map { |msg| msg.scan(@issue_key_pattern) }.uniq
end

#extract_reviews(raw_reviews) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jirametrics/github_gateway.rb', line 73

def extract_reviews raw_reviews
  raw_reviews
    .select { |r| %w[APPROVED CHANGES_REQUESTED].include?(r['state']) }
    .map do |r|
      {
        'author'       => r.dig('author', 'login'),
        'submitted_at' => r['submittedAt'],
        'state'        => r['state']
      }
    end
end

#fetch_pull_requests(since: nil) ⇒ Object



17
18
19
20
# File 'lib/jirametrics/github_gateway.rb', line 17

def fetch_pull_requests since: nil
  raw_prs = @raw_pr_cache[[@repo, since]] ||= fetch_raw_pull_requests(since: since)
  raw_prs.filter_map { |pr| build_pr_data(pr) }
end

#fetch_raw_pull_requests(since: nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/jirametrics/github_gateway.rb', line 22

def fetch_raw_pull_requests since: nil
  # Note: 'commits' is intentionally excluded — including it triggers GitHub's GraphQL node
  # limit (authors sub-connection × PRs × commits exceeds 500,000 nodes). Branch name,
  # title, and body are sufficient for issue key extraction in the vast majority of cases.
  json_fields = %w[number title body headRefName createdAt closedAt mergedAt
                   url state reviews additions deletions changedFiles].join(',')
  args = ['pr', 'list', '--state', 'all', '--limit', '5000', '--json', json_fields]
  args += ['--repo', @repo]
  args += ['--search', "updated:>=#{since}"] if since

  @file_system.log "  Downloading pull requests from #{@repo}", also_write_to_stderr: true
  run_command(args)
end