Class: Inq::Sources::Github::IssueFetcher

Inherits:
Object
  • Object
show all
Includes:
DateTimeHelpers
Defined in:
lib/inq/sources/github/issue_fetcher.rb

Overview

Fetches raw data for GitHub issues.

Constant Summary collapse

END_LOOP =
:terminate_graphql_loop
GRAPHQL_QUERY =
<<~QUERY
  repository(owner: %{user}, name: %{repo}) {
    %{type}(first: %{chunk_size}%{after_str}, orderBy:{field: CREATED_AT, direction: ASC}) {
      edges {
        cursor
        node {
          number
          createdAt
          closedAt
          updatedAt
          state
          title
          url
          labels(first: 100) {
            nodes {
              name
            }
          }
        }
      }
    }
  }
QUERY
CHUNK_SIZE =
100

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from DateTimeHelpers

#date_ge, #date_le

Constructor Details

#initialize(issues_source) ⇒ IssueFetcher

Returns a new instance of IssueFetcher.

Parameters:

  • issues_source (Issues)

    Inq::Issues or Inq::Pulls instance for which to fetch issues



47
48
49
50
51
52
53
54
55
56
# File 'lib/inq/sources/github/issue_fetcher.rb', line 47

def initialize(issues_source)
  @issues_source = issues_source
  @cache = issues_source.cache
  @github = Sources::Github.new(issues_source.config)
  @repository = issues_source.config["repository"]
  @user, @repo = @repository.split("/", 2)
  @start_date = issues_source.start_date
  @end_date = issues_source.end_date
  @type = issues_source.type
end

Instance Attribute Details

#typeObject (readonly)

Returns the value of attribute type.



44
45
46
# File 'lib/inq/sources/github/issue_fetcher.rb', line 44

def type
  @type
end

Instance Method Details

#build_query(user, repo, type, after_str) ⇒ Object



124
125
126
127
128
129
130
131
132
# File 'lib/inq/sources/github/issue_fetcher.rb', line 124

def build_query(user, repo, type, after_str)
  format(GRAPHQL_QUERY, {
    user: user.inspect,
    repo: repo.inspect,
    type: type,
    chunk_size: CHUNK_SIZE,
    after_str: after_str,
  })
end

#dataObject



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/inq/sources/github/issue_fetcher.rb', line 58

def data
  return @data if instance_variable_defined?(:@data)

  @data = []
  return @data if last_cursor.nil?

  Inq::Text.print "Fetching #{@repository} #{@issues_source.pretty_type} data."

  @data = @cache.cached("fetch-#{type}") do
    data = []
    after, data = fetch_issues(after, data) until after == END_LOOP
    data.select(&method(:issue_is_relevant?))
  end

  Inq::Text.puts

  @data
end

#edge_nodes(edges) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/inq/sources/github/issue_fetcher.rb', line 134

def edge_nodes(edges)
  return [] if edges.nil?
  new_data = edges.map { |issue|
    node = issue["node"]
    node["labels"] = node["labels"]["nodes"]

    node
  }

  new_data
end

#fetch_issues(after, data) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/inq/sources/github/issue_fetcher.rb', line 107

def fetch_issues(after, data)
  Inq::Text.print "."

  after_str = ", after: #{after.inspect}" unless after.nil?

  query = build_query(@user, @repo, type, after_str)
  raw_data = @github.graphql(query)
  edges = raw_data.dig("data", "repository", type, "edges")

  data += edge_nodes(edges)

  next_cursor = edges.last["cursor"]
  next_cursor = END_LOOP if next_cursor == last_cursor

  [next_cursor, data]
end

#issue_is_relevant?(issue) ⇒ Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
83
# File 'lib/inq/sources/github/issue_fetcher.rb', line 77

def issue_is_relevant?(issue)
  if !issue["closedAt"].nil? && date_le(issue["closedAt"], @start_date)
    false
  else
    date_ge(issue["createdAt"], @start_date) && date_le(issue["createdAt"], @end_date)
  end
end

#last_cursorObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/inq/sources/github/issue_fetcher.rb', line 85

def last_cursor
  return @last_cursor if instance_variable_defined?(:@last_cursor)

  raw_data = @github.graphql <<~QUERY
    repository(owner: #{@user.inspect}, name: #{@repo.inspect}) {
      #{type}(last: 1, orderBy:{field: CREATED_AT, direction: ASC}) {
        edges {
          cursor
        }
      }
    }
  QUERY

  edges = raw_data.dig("data", "repository", type, "edges")
  @last_cursor =
    if edges.nil? || edges.empty?
      nil
    else
      edges.last["cursor"]
    end
end