mirror of https://github.com/saimn/sigal.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
4.0 KiB
141 lines
4.0 KiB
""" |
|
Script to generate contributor and pull request lists |
|
|
|
This script generates contributor and pull request lists for release |
|
changelogs using Github v3 protocol. Use requires an authentication token in |
|
order to have sufficient bandwidth, you can get one following the directions at |
|
`<https://help.github.com/articles/creating-an-access-token-for-command-line-use/>_ |
|
Don't add any scope, as the default is read access to public information. The |
|
token may be stored in an environment variable as you only get one chance to |
|
see it. |
|
|
|
Usage:: |
|
|
|
$ python ./docs/changelog.py <token> <revision range> |
|
|
|
The output is utf8 rst. |
|
|
|
Dependencies |
|
------------ |
|
|
|
- gitpython |
|
- pygithub |
|
|
|
This script comes from Numpy: |
|
https://github.com/numpy/numpy/blob/main/tools/changelog.py |
|
|
|
Examples |
|
-------- |
|
|
|
From the bash command line with $GITHUB token:: |
|
|
|
$ ./docs/changelog.py $GITHUB 1.4.0..main |
|
|
|
""" |
|
|
|
import os |
|
import re |
|
|
|
from git import Repo |
|
|
|
from github import Github |
|
|
|
this_repo = Repo(os.path.join(os.path.dirname(__file__), "..")) |
|
|
|
author_msg = """ |
|
A total of %d people contributed to this release. People with a "+" by their |
|
names contributed a patch for the first time. |
|
""" |
|
|
|
pull_request_msg = """ |
|
A total of %d pull requests were merged for this release. |
|
""" |
|
|
|
|
|
def get_authors(revision_range): |
|
pat = '^.*\\t(.*)$' |
|
lst_release, cur_release = [r.strip() for r in revision_range.split('..')] |
|
|
|
# authors, in current release and previous to current release. |
|
cur = set(re.findall(pat, this_repo.git.shortlog('-s', revision_range), |
|
re.M)) |
|
pre = set(re.findall(pat, this_repo.git.shortlog('-s', lst_release), |
|
re.M)) |
|
|
|
# Append '+' to new authors. |
|
authors = [s + ' +' for s in cur - pre] + [s for s in cur & pre] |
|
authors.sort() |
|
return authors |
|
|
|
|
|
def get_pull_requests(repo, revision_range): |
|
prnums = [] |
|
|
|
# From regular merges |
|
merges = this_repo.git.log( |
|
'--oneline', '--merges', revision_range) |
|
issues = re.findall("Merge pull request \\#(\\d*)", merges) |
|
prnums.extend(int(s) for s in issues) |
|
|
|
# From Homu merges (Auto merges) |
|
issues = re. findall("Auto merge of \\#(\\d*)", merges) |
|
prnums.extend(int(s) for s in issues) |
|
|
|
# From fast forward squash-merges |
|
commits = this_repo.git.log( |
|
'--oneline', '--no-merges', '--first-parent', revision_range) |
|
issues = re.findall('^.*\\(\\#(\\d+)\\)$', commits, re.M) |
|
prnums.extend(int(s) for s in issues) |
|
|
|
# get PR data from github repo |
|
prnums.sort() |
|
prs = [repo.get_pull(n) for n in prnums] |
|
return prs |
|
|
|
|
|
def main(token, revision_range): |
|
lst_release, cur_release = [r.strip() for r in revision_range.split('..')] |
|
|
|
github = Github(token) |
|
github_repo = github.get_repo('saimn/sigal') |
|
|
|
# document authors |
|
authors = get_authors(revision_range) |
|
heading = "Contributors" |
|
print() |
|
print(heading) |
|
print("=" * len(heading)) |
|
print(author_msg % len(authors)) |
|
|
|
for s in authors: |
|
print('* ' + s) |
|
|
|
# document pull requests |
|
pull_requests = get_pull_requests(github_repo, revision_range) |
|
heading = "Pull requests merged" |
|
pull_msg = "* `#{0} <{1}>`__: {2}" |
|
|
|
print() |
|
print(heading) |
|
print("=" * len(heading)) |
|
print(pull_request_msg % len(pull_requests)) |
|
|
|
for pull in pull_requests: |
|
title = re.sub("\\s+", " ", pull.title.strip()) |
|
if len(title) > 60: |
|
remainder = re.sub("\\s.*$", "...", title[60:]) |
|
if len(remainder) > 20: |
|
remainder = title[:80] + "..." |
|
else: |
|
title = title[:60] + remainder |
|
print(pull_msg.format(pull.number, pull.html_url, title)) |
|
|
|
|
|
if __name__ == "__main__": |
|
from argparse import ArgumentParser |
|
|
|
parser = ArgumentParser(description="Generate author/pr lists for release") |
|
parser.add_argument('token', help='github access token') |
|
parser.add_argument('revision_range', help='<revision>..<revision>') |
|
args = parser.parse_args() |
|
main(args.token, args.revision_range)
|
|
|