Skip to content

Instantly share code, notes, and snippets.

@fudanchii
Last active September 27, 2020 14:49
Show Gist options
  • Save fudanchii/b9d5f57f49feb9b655465c5246cd612f to your computer and use it in GitHub Desktop.
Save fudanchii/b9d5f57f49feb9b655465c5246cd612f to your computer and use it in GitHub Desktop.
require "rubygems"
require "bundler"
Bundler.require(:default)
def find_ref(body)
refs = body.split("\n").map do |line|
next unless line =~ /https:/
line.gsub(%r{.*(https://[^\s\)">]+).*}, '\1')
end
.compact
.select { |url| !%w(.jpg .jpeg .png .gif).include?(File.extname(url)) }
.join("\n")
return nil if refs == body
refs
end
def search_query(last_cursor:, predicates:[])
{
variables: {
query: predicates.compact.join(" "),
cursor: last_cursor,
},
query: <<~GQL
query search($query: String!, $cursor: String) {
search(query: $query, type: ISSUE, first: 100, after: $cursor) {
nodes {
...pullRequestFragment
}
pageInfo {
hasNextPage
endCursor
}
}
}
fragment pullRequestFragment on PullRequest {
author { login }
title
body
createdAt
url
state
}
GQL
}
end
def search_by_author(cursor:, since:, org:, repo:, login:)
query = search_query(
last_cursor: cursor,
predicates: [
"is:pr",
"created:>=#{since}",
"author:#{login}",
"org:#{org}",
"repo:#{repo}"
]
).to_json
gh_client.post("/graphql", query)
end
def author(since:, org:, repo:, member_logins:)
nodes = []
member_logins.each do |login|
has_next = true
cursor = nil
while has_next
puts "querying PRs created by: #{login}"
response = search_by_author(cursor: cursor, since: since, org: org, repo: repo, login: login)
response = response[:data][:search]
nodes += response[:nodes]
has_next = response[:pageInfo][:hasNextPage]
cursor = response[:pageInfo][:endCursor]
end
sleep(2)
end
nodes
end
def scan_author(since:, org:, repo:, member_logins:)
nodes = author(since: since, org: org, repo: repo, member_logins: member_logins)
CSV.open(ENV.fetch("CSV_FILENAME", "author_org-#{org}_since-#{since}.csv"), "wb") do |csv|
csv << %w(created status author title url ref)
nodes.each do |node|
date = Date.parse(node[:createdAt]).iso8601 rescue nil
login = node[:author][:login] rescue node[:author]
title = node[:title]
ref = find_ref(node[:body] || '')
url = node[:url]
status = node[:state]
csv << [date, status, login, title, url, ref]
end
end
end
def search_by_reviewer(cursor:, since:, org:, repo:, login:)
query = search_query(
last_cursor: cursor,
predicates: [
"is:pr",
"created:>=#{since}",
"reviewed-by:#{login}",
"org:#{org}",
"repo:#{repo}"
]
).to_json
gh_client.post("/graphql", query)
end
def reviewer(since:, org:, repo:, member_logins:)
nodes = []
member_logins.each do |login|
has_next = true
cursor = nil
while has_next
puts "querying PRs reviewed by: #{login}"
response = search_by_reviewer(cursor: cursor, since: since, org: org, repo: repo, login: login)
response = response[:data][:search]
nodes += response[:nodes].map { |node| node[:reviewer] = login; node }
has_next = response[:pageInfo][:hasNextPage]
cursor = response[:pageInfo][:endCursor]
end
sleep(2)
end
nodes
end
def scan_reviewer(since:, org:, repo:, member_logins:)
nodes = reviewer(since: since, org: org, repo: repo, member_logins: member_logins)
CSV.open(ENV.fetch("CSV_FILENAME", "reviewer_org-#{org}_since-#{since}.csv"), "wb") do |csv|
csv << %w(created status reviewer title url ref)
nodes.each do |node|
date = Date.parse(node[:createdAt]).iso8601 rescue nil
login = node[:reviewer]
title = node[:title]
ref = find_ref(node[:body] || '')
url = node[:url]
status = node[:state]
csv << [date, status, login, title, url, ref]
end
end
end
def gh_client
@gh_client ||= Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"])
end
logins = ENV["GITHUB_LOGINS"].split(",")
if ENV["USE_GITHUB_TEAM"] == "true"
team_id = ENV.fetch("GITHUB_TEAM_ID", 2265354)
logins = gh_client.team_members(team_id).map(&:login)
end
scan_author(since: "2020-03-16", org: "quipper", repo: "quipper/monorepo-global", member_logins: logins)
scan_reviewer(since: "2020-03-16", org: "quipper", repo: "quipper/monorepo-global", member_logins: logins)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment