summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2016-10-02 15:35:37 -0600
committerCharles Harris <charlesr.harris@gmail.com>2016-10-03 20:54:58 -0600
commit529128134d92facd5728525c77a58397e87f0a38 (patch)
tree59302c7f3221cf7332b410e9b5db3b3671d64f8b /tools
parent86c780d1c60473b594db7a241419167ebc3df687 (diff)
downloadpython-numpy-529128134d92facd5728525c77a58397e87f0a38.tar.gz
python-numpy-529128134d92facd5728525c77a58397e87f0a38.tar.bz2
python-numpy-529128134d92facd5728525c77a58397e87f0a38.zip
ENH: Add a tool for release authors and PRs.
Add the script tools/announce.py to generate the author and pull request lists needed in release announcements. Some bits of this are taken from the scipy gh_list.py and authors.py tools. Usage: $ ./tools/announce.py <github_user> <github_password> <revision_range> The output is utf8 rst. [ci skip]
Diffstat (limited to 'tools')
-rwxr-xr-xtools/announce.py117
1 files changed, 117 insertions, 0 deletions
diff --git a/tools/announce.py b/tools/announce.py
new file mode 100755
index 000000000..309a78a9d
--- /dev/null
+++ b/tools/announce.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# -*- encoding:utf-8 -*-
+"""
+Script to generate contribor and pull request lists
+
+This script generates contributor and pull request lists for release
+announcements 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::
+
+ $ ./tools/announce.py <token> <revision range>
+
+The output is utf8 rst.
+
+Dependencies
+------------
+
+- gitpython
+- pygithub
+
+Some code was copied from scipy `tools/gh_list.py` and `tools/authors.py`.
+
+Examples
+--------
+
+From the bash command line with $GITHUB token.
+
+ $ ./tools/announce $GITHUB v1.11.0..v1.11.1 > announce.rst
+
+"""
+from __future__ import print_function, division
+
+import os
+import sys
+import re
+import codecs
+from git import Repo
+from github import Github
+
+UTF8Writer = codecs.getwriter('utf8')
+sys.stdout = UTF8Writer(sys.stdout)
+this_repo = Repo(os.path.join(os.path.dirname(__file__), ".."))
+
+author_msg =\
+u"""
+A total of %d people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+"""
+
+
+def get_authors(revision_range):
+ pat = u'.*\\t(.*)\\n'
+ lst_release, cur_release = [r.strip() for r in revision_range.split('..')]
+
+ cur = set(re.findall(pat, this_repo.git.shortlog('-s', revision_range)))
+ pre = set(re.findall(pat, this_repo.git.shortlog('-s', lst_release)))
+ authors = [s + u' +' for s in cur - pre] + [s for s in cur & pre]
+ authors.sort()
+ return authors
+
+
+def get_prs(repo, revision_range):
+ merges = this_repo.git.log('--oneline', '--merges', revision_range)
+ issues = re.findall(u"Merge pull request \#(\d*)", merges)
+ prnums = [int(s) for s in issues]
+ prs = [repo.get_pull(n) for n in sorted(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('numpy/numpy')
+
+ # document authors
+ authors = get_authors(revision_range)
+ heading = u"Contributors to {0}".format(cur_release)
+ print()
+ print(heading)
+ print(u"-"*len(heading))
+ print()
+ for s in authors:
+ print(u'- ' + s)
+ print(author_msg % len(authors))
+
+ # document pull requests
+ heading = u"Pull requests merged for {0}".format(cur_release)
+ print()
+ print(heading)
+ print(u"-"*len(heading))
+ print()
+ for pull in get_prs(github_repo, revision_range):
+ pull_msg = u"- `#{0} <{1}>`__: {2}"
+ title = re.sub(u"\s+", u" ", pull.title.strip())
+ if len(title) > 60:
+ remainder = re.sub(u"\s.*$", u"...", title[60:])
+ if len(remainder) > 20:
+ remainder = title[:80] + u"..."
+ 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)