Skip to content

Instantly share code, notes, and snippets.

@dafurman
Created February 11, 2024 21:16
Show Gist options
  • Save dafurman/b7a4079ebd0c7b6e67b3e652d20ca3c5 to your computer and use it in GitHub Desktop.
Save dafurman/b7a4079ebd0c7b6e67b3e652d20ca3c5 to your computer and use it in GitHub Desktop.
Print the top 10 Github contributors in some repos in an org since a given date
#!/usr/bin/env python3
# Note: For my simple use case, repo count is hardcoded to 3 repos from the same owner. Adjust this to whatever you need.
import sys
import time
from collections import defaultdict
from ghapi.all import GhApi
if len(sys.argv) < 7 or len(sys.argv) > 8:
print("Usage: {} token owner repo1 repo2 repo3 start_date [verbose]".format(sys.argv[0]))
sys.exit(1)
TOKEN = sys.argv[1]
OWNER = sys.argv[2]
repos = [(OWNER, repo) for repo in sys.argv[3:6]]
START_DATE = sys.argv[6]
verbose = len(sys.argv) == 8 and sys.argv[7] == "verbose"
api = GhApi(token=TOKEN)
def merge_dicts(dict1, dict2):
merged_dict = dict1.copy()
for key, value in dict2.items():
if key in merged_dict:
merged_dict[key] += value
else:
merged_dict[key] = value
return merged_dict
def print_contributions(contributions_dict, repo):
print("Top 10 contributors from {} onwards in {}:".format(START_DATE, repo))
print("Rank\tContributor\tContributions")
sorted_contributions = sorted(contributions_dict.items(), key=lambda x: x[1], reverse=True)[:10]
max_len_contributor = max(len(contributor) for contributor, _ in sorted_contributions)
for i, (contributor, count) in enumerate(sorted_contributions, start=1):
print(f"{i}\t{contributor.ljust(max_len_contributor)}\t{count}")
print("\n")
total_contributions = defaultdict(int)
for owner, repo in repos:
try:
contributors = api.repos.list_contributors(owner=OWNER, repo=repo)
except Exception as e:
print("Error fetching contributors:", e)
sys.exit(1)
contributors_logins = [contributor['login'] for contributor in contributors]
print("Gathering data...")
print(f"Contributions for {owner}/{repo} from {START_DATE} onwards:")
repo_contributions_by_login = defaultdict(int)
for contributor in contributors_logins:
if contributor.endswith("bot"):
continue # Skip contributors with "bot" suffix
try:
search_result = api.search.issues_and_pull_requests(
q=f"repo:{owner}/{repo} is:merged author:{contributor} created:>{START_DATE}"
)
contributions = search_result['total_count']
except Exception as e:
print(f"Error fetching contributions for {contributor}:", e)
contributions = 0
if verbose:
print(f"{contributor}: {contributions}")
repo_contributions_by_login[contributor] = contributions
time.sleep(10) # dumb hack to avoid API rate limiting
total_contributions = merge_dicts(total_contributions, repo_contributions_by_login)
print_contributions(contributions_dict=repo_contributions_by_login, repo=repo)
print_contributions(contributions_dict=total_contributions, repo="All repos")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment