2020-08-03 10:57:44 +03:00
|
|
|
import json
|
2021-11-09 13:32:08 +03:00
|
|
|
import os
|
2020-08-03 10:57:44 +03:00
|
|
|
from pathlib import Path
|
2021-11-09 14:53:02 +03:00
|
|
|
|
2020-08-11 19:17:12 +03:00
|
|
|
from github import Github
|
|
|
|
from github.NamedUser import NamedUser
|
2020-08-03 10:57:44 +03:00
|
|
|
from jinja2 import Template
|
|
|
|
|
|
|
|
CURRENT_FILE = Path(__file__)
|
|
|
|
ROOT = CURRENT_FILE.parents[1]
|
|
|
|
BOT_LOGINS = ["pyup-bot"]
|
2021-11-09 13:32:08 +03:00
|
|
|
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN", None)
|
|
|
|
GITHUB_REPO = os.getenv("GITHUB_REPOSITORY", None)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
2020-08-10 20:30:36 +03:00
|
|
|
"""
|
|
|
|
Script entry point.
|
|
|
|
|
2020-09-04 18:27:09 +03:00
|
|
|
1. Fetch recent contributors from the Github API
|
2020-08-10 20:30:36 +03:00
|
|
|
2. Add missing ones to the JSON file
|
|
|
|
3. Generate Markdown from JSON file
|
|
|
|
"""
|
2020-08-11 19:17:12 +03:00
|
|
|
recent_authors = set(iter_recent_authors())
|
2020-08-10 20:13:42 +03:00
|
|
|
|
2020-08-10 20:30:36 +03:00
|
|
|
# Add missing users to the JSON file
|
2020-08-03 10:57:44 +03:00
|
|
|
contrib_file = ContributorsJSONFile()
|
2020-08-11 19:17:12 +03:00
|
|
|
for author in recent_authors:
|
|
|
|
print(f"Checking if {author.login} should be added")
|
|
|
|
if author.login not in contrib_file:
|
|
|
|
contrib_file.add_contributor(author)
|
|
|
|
print(f"Added {author.login} to contributors")
|
2020-08-03 10:57:44 +03:00
|
|
|
contrib_file.save()
|
|
|
|
|
2020-08-10 20:30:36 +03:00
|
|
|
# Generate MD file from JSON file
|
2020-08-10 19:42:01 +03:00
|
|
|
write_md_file(contrib_file.content)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
|
2020-08-11 19:17:12 +03:00
|
|
|
def iter_recent_authors():
|
|
|
|
"""
|
|
|
|
Fetch users who opened recently merged pull requests.
|
2020-08-03 10:57:44 +03:00
|
|
|
|
2020-08-11 19:17:12 +03:00
|
|
|
Use Github API to fetch recent authors rather than
|
|
|
|
git CLI to work with Github usernames.
|
|
|
|
"""
|
2021-11-09 13:32:08 +03:00
|
|
|
repo = Github(login_or_token=GITHUB_TOKEN, per_page=5).get_repo(GITHUB_REPO)
|
2023-04-15 17:43:04 +03:00
|
|
|
recent_pulls = repo.get_pulls(state="closed", sort="updated", direction="desc").get_page(0)
|
2020-08-11 19:17:12 +03:00
|
|
|
for pull in recent_pulls:
|
2023-04-15 17:43:04 +03:00
|
|
|
if pull.merged and pull.user.type == "User" and pull.user.login not in BOT_LOGINS:
|
2020-08-11 19:17:12 +03:00
|
|
|
yield pull.user
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
|
|
|
|
class ContributorsJSONFile:
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Helper to interact with the JSON file."""
|
|
|
|
|
2020-08-03 10:57:44 +03:00
|
|
|
file_path = ROOT / ".github" / "contributors.json"
|
|
|
|
content = None
|
|
|
|
|
|
|
|
def __init__(self) -> None:
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Read initial content."""
|
2020-08-10 19:42:01 +03:00
|
|
|
self.content = json.loads(self.file_path.read_text())
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
def __contains__(self, github_login: str):
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Provide a nice API to do: `username in file`."""
|
2020-08-14 10:27:57 +03:00
|
|
|
return any(
|
|
|
|
# Github usernames are case insensitive
|
|
|
|
github_login.lower() == contrib["github_login"].lower()
|
|
|
|
for contrib in self.content
|
|
|
|
)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
2020-08-11 19:17:12 +03:00
|
|
|
def add_contributor(self, user: NamedUser):
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Append the contributor data we care about at the end."""
|
2020-08-03 10:57:44 +03:00
|
|
|
contributor_data = {
|
2020-08-11 19:17:12 +03:00
|
|
|
"name": user.name or user.login,
|
|
|
|
"github_login": user.login,
|
|
|
|
"twitter_username": user.twitter_username or "",
|
2020-08-03 10:57:44 +03:00
|
|
|
}
|
2020-08-10 20:30:36 +03:00
|
|
|
self.content.append(contributor_data)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
def save(self):
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Write the file to disk with indentation."""
|
2020-08-10 19:46:34 +03:00
|
|
|
text_content = json.dumps(self.content, indent=2, ensure_ascii=False)
|
|
|
|
self.file_path.write_text(text_content)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
|
2020-08-10 19:42:01 +03:00
|
|
|
def write_md_file(contributors):
|
2020-08-10 20:30:36 +03:00
|
|
|
"""Generate markdown file from Jinja template."""
|
2020-08-10 20:35:04 +03:00
|
|
|
contributors_template = ROOT / ".github" / "CONTRIBUTORS-template.md"
|
|
|
|
template = Template(contributors_template.read_text(), autoescape=True)
|
2020-08-10 19:46:34 +03:00
|
|
|
core_contributors = [c for c in contributors if c.get("is_core", False)]
|
|
|
|
other_contributors = (c for c in contributors if not c.get("is_core", False))
|
2020-08-10 20:18:09 +03:00
|
|
|
other_contributors = sorted(other_contributors, key=lambda c: c["name"].lower())
|
2023-04-15 17:43:04 +03:00
|
|
|
content = template.render(core_contributors=core_contributors, other_contributors=other_contributors)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
2020-08-10 19:42:01 +03:00
|
|
|
file_path = ROOT / "CONTRIBUTORS.md"
|
|
|
|
file_path.write_text(content)
|
2020-08-03 10:57:44 +03:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2021-11-09 13:32:08 +03:00
|
|
|
if GITHUB_REPO is None:
|
2023-04-15 17:43:04 +03:00
|
|
|
raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY")
|
2020-08-10 19:42:01 +03:00
|
|
|
main()
|