Skip to content

Instantly share code, notes, and snippets.

@introt
Last active December 4, 2022 22:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save introt/ad30bcbdf789aed5bba43082741c7769 to your computer and use it in GitHub Desktop.
Save introt/ad30bcbdf789aed5bba43082741c7769 to your computer and use it in GitHub Desktop.
"Co-authored-by" lines from usernames and issue/PR urls using GitHub REST API
#!/usr/bin/env python3
"""
coauthor.py - credit GitHub users easily
Supports both issue and pull request urls
in addition to GitHub usernames.
Use directly in vim: ":r ! coauthor.py introt" or ":r ! coauthor.py https://github.com/user/repo/pull/1"".
Sample output:
Co-authored-by: introt <26069787+introt@users.noreply.github.com>
"""
# SPDX-FileCopyrightText: 2022 introt <introt@koti.fimnet.fi>
#
# SPDX-License-Identifier: MIT-Modern-Variant
from json import load
from urllib import request
def p(s):
# TODO: make printing title and/or original repo/PR optional - commented out for now
#print(s)
pass
def get_user(username: str) -> dict:
""" Get the ``user`` object via the GitHub REST API. """
return load(request.urlopen(f'https://api.github.com/users/{username}'))
def get_issue(issue_url: str) -> dict:
""" Get the ``pull`` or ``issue`` object via the GitHub REST API. """
tokens = issue_url.split('/')
github = tokens.index('github.com')
user, repo, issue, pr, *trailing = tokens[github+1:]
issue.replace('pull', 'pulls')
p(f'{user}/{repo}#{pr}')
return load(request.urlopen(f'https://api.github.com/repos/{user}/{repo}/{issue}/{pr}'))
def noreply_email(user: dict):
""" Get the noreply email from a ``user`` object. """
# f-string: unmatched '[' without this
uid = user['id']
login = user['login']
return f'{uid}+{login}@users.noreply.github.com'
def coauthor(author: str) -> str:
""" Get the co-author string.
:var author: GitHub username
"""
user = get_user(author)
email = noreply_email(user)
name = user['name'] or user['login']
return f'Co-authored-by: {name} <{email}>'
def issue_coauthor(issue_url: str):
""" Get the co-author string.
:var issue_url: Pull request url
"""
pull = get_issue(issue_url)
p(pull['title'] + '\n\n')
# pull user doesn't include name!
return coauthor(pull['user']['login'])
if __name__ == '__main__':
import sys
x = sys.argv[1]
if x.startswith('https://'):
print(issue_coauthor(x))
else:
print(coauthor(x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment