Created
February 11, 2024 21:16
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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