Skip to content

Instantly share code, notes, and snippets.

@arfon
Created January 31, 2014 04:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save arfon/8726472 to your computer and use it in GitHub Desktop.
Save arfon/8726472 to your computer and use it in GitHub Desktop.
Octostats
require 'octokit'
require 'csv'
require 'hashie'
require 'active_support/all'
class PR < Hashie::Dash
property :pr
property :created_at
property :comment_count
property :commit_count
property :collaborative
property :merged
def merged?
merged == "1"
end
def collaborative?
collaborative == "1"
end
end
repos = [ { :name => 'spine/spine', :alias => 'spine' },
{ :name => 'octokit/octokit.rb', :alias => 'octokit' },
{ :name => 'github/linguist', :alias => 'linguist'}]
Octokit.auto_paginate = true
client = Octokit::Client.new(access_token: "xxxxxxxxxxxxxxx")
repos.each do |repo|
closed = client.pulls(repo[:name], 'closed')
pull_requests = []
closed.each do |pr|
pull_requests << { :number => pr.number, :created_at => pr.created_at }
end
open = client.pulls(repo[:name], 'open')
open.each do |pr|
pull_requests << { :number => pr.number, :created_at => pr.created_at }
end
puts "Working with #{pull_requests.count} pull requests"
results = File.new("#{repo[:alias]}_raw_prs.csv", 'w')
results.puts "pr,created_at,comment_count,commit_count,collaborative,merged"
pull_requests.each do |pr|
pull_request = client.pull_request(repo, pr[:number])
pull_request_commits = client.pull_request_commits(repo, pr[:number])
collaborative = 0
merged = 0
# Skip if the PR has zero commits
next unless pull_request_commits.any?
# Were more commits added to the PR over time
if pull_request_commits.last.commit.committer.date > pull_request.created_at
collaborative = 1
end
if pull_request.merged
merged = 1
end
result = "#{pr[:number]},#{pr[:created_at]},#{pull_request.comments},#{pull_request.commits},#{collaborative},#{merged}"
puts result
results.puts result
end
results.close
prs = []
CSV.foreach("#{repo[:alias]}_raw_prs.csv", :headers => true) do |row|
prs << PR.new(row.to_hash)
end
prs_grouped_by_month = prs.group_by { |m| m.created_at.to_date.beginning_of_month }
# Now we want the merge fraction over time for pull requests. This means looping
# through PRs grouped by week and calculating the fraction that are closed.
merged_fraction_results = File.new("#{repo[:alias]}_merged_fraction.tsv", 'w')
merged_fraction_results.puts("date\tunix_date\tmerged_count\tnot_merged_count\tcount\tmerge_fraction")
total_prs = prs.count
total_merged = 0
prs_grouped_by_month.sort.each do |month, prs|
merged_count = 0
prs.each do |pr|
merged_count += 1 if pr.merged?
total_merged += 1 if pr.merged?
end
f_merged = merged_count.to_f / prs.size.to_f
merged_fraction_results.puts("#{month.to_s}\t#{month.to_datetime.to_i*1000}\t#{merged_count}\t#{prs.size-merged_count}\t#{prs.size}\t#{f_merged}")
end
# Overall stats (for debug)
puts "#{repo[:alias]} is #{(total_merged.to_f / total_prs) * 100}% merged"
merged_fraction_results.close
collaborative_fraction_results = File.new("#{repo[:alias]}_collaborative_fraction.tsv", 'w')
collaborative_fraction_results.puts("date\tunix_date\tcollab_count\tnot_collab_count\tcount\tcollab_fraction")
total_collab = 0
prs_grouped_by_month.sort.each do |month, prs|
collab_count = 0
prs.each do |pr|
collab_count += 1 if pr.collaborative?
total_collab += 1 if pr.collaborative?
end
f_colab = collab_count.to_f / prs.size.to_f
collaborative_fraction_results.puts("#{month.to_s}\t#{month.to_datetime.to_i*1000}\t#{collab_count}\t#{prs.size-collab_count}\t#{prs.size}\t#{f_colab}")
end
# Overall stats (for debug)
puts "#{repo[:alias]} is #{(total_collab.to_f / total_prs) * 100}% collaborative"
collaborative_fraction_results.close
end
@parthan-sundararajan
Copy link

This gist is outdated. Kindly check the fix if you get an error related to octokit - octokit/octokit.rb#937

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment