Show More
@@ -181,6 +181,18 b' def is_pull_request(issue):' | |||||
181 | """Return True if the given issue is a pull request.""" |
|
181 | """Return True if the given issue is a pull request.""" | |
182 | return bool(issue.get('pull_request', {}).get('html_url', None)) |
|
182 | return bool(issue.get('pull_request', {}).get('html_url', None)) | |
183 |
|
183 | |||
|
184 | def get_authors(pr): | |||
|
185 | print("getting authors for #%i" % pr['number'], file=sys.stderr) | |||
|
186 | h = make_auth_header() | |||
|
187 | r = requests.get(pr['commits_url'], headers=h) | |||
|
188 | r.raise_for_status() | |||
|
189 | commits = r.json() | |||
|
190 | authors = [] | |||
|
191 | for commit in commits: | |||
|
192 | author = commit['commit']['author'] | |||
|
193 | authors.append("%s <%s>" % (author['name'], author['email'])) | |||
|
194 | return authors | |||
|
195 | ||||
184 | # encode_multipart_formdata is from urllib3.filepost |
|
196 | # encode_multipart_formdata is from urllib3.filepost | |
185 | # The only change is to iter_fields, to enforce S3's required key ordering |
|
197 | # The only change is to iter_fields, to enforce S3's required key ordering | |
186 |
|
198 |
@@ -17,9 +17,10 b' import sys' | |||||
17 | from argparse import ArgumentParser |
|
17 | from argparse import ArgumentParser | |
18 | from datetime import datetime, timedelta |
|
18 | from datetime import datetime, timedelta | |
19 | from subprocess import check_output |
|
19 | from subprocess import check_output | |
|
20 | ||||
20 | from gh_api import ( |
|
21 | from gh_api import ( | |
21 | get_paged_request, make_auth_header, get_pull_request, is_pull_request, |
|
22 | get_paged_request, make_auth_header, get_pull_request, is_pull_request, | |
22 | get_milestone_id, get_issues_list, |
|
23 | get_milestone_id, get_issues_list, get_authors, | |
23 | ) |
|
24 | ) | |
24 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
25 | # Globals |
|
26 | # Globals | |
@@ -101,10 +102,10 b' def report(issues, show_urls=False):' | |||||
101 | for i in issues: |
|
102 | for i in issues: | |
102 | role = 'ghpull' if 'merged_at' in i else 'ghissue' |
|
103 | role = 'ghpull' if 'merged_at' in i else 'ghissue' | |
103 | print('* :%s:`%d`: %s' % (role, i['number'], |
|
104 | print('* :%s:`%d`: %s' % (role, i['number'], | |
104 | i['title'].encode('utf-8'))) |
|
105 | i['title'].replace('`', '``').encode('utf-8'))) | |
105 | else: |
|
106 | else: | |
106 | for i in issues: |
|
107 | for i in issues: | |
107 | print('* %d: %s' % (i['number'], i['title'].encode('utf-8'))) |
|
108 | print('* %d: %s' % (i['number'], i['title'].replace('`', '``').encode('utf-8'))) | |
108 |
|
109 | |||
109 | #----------------------------------------------------------------------------- |
|
110 | #----------------------------------------------------------------------------- | |
110 | # Main script |
|
111 | # Main script | |
@@ -160,14 +161,15 b' if __name__ == "__main__":' | |||||
160 | if milestone: |
|
161 | if milestone: | |
161 | milestone_id = get_milestone_id(project=project, milestone=milestone, |
|
162 | milestone_id = get_milestone_id(project=project, milestone=milestone, | |
162 | auth=True) |
|
163 | auth=True) | |
163 | issues = get_issues_list(project=project, |
|
164 | issues_and_pulls = get_issues_list(project=project, | |
164 | milestone=milestone_id, |
|
165 | milestone=milestone_id, | |
165 | state='closed', |
|
166 | state='closed', | |
166 | auth=True, |
|
167 | auth=True, | |
167 | ) |
|
168 | ) | |
|
169 | issues, pulls = split_pulls(issues_and_pulls) | |||
168 | else: |
|
170 | else: | |
169 | issues = issues_closed_since(since, project=project, pulls=False) |
|
171 | issues = issues_closed_since(since, project=project, pulls=False) | |
170 | pulls = issues_closed_since(since, project=project, pulls=True) |
|
172 | pulls = issues_closed_since(since, project=project, pulls=True) | |
171 |
|
173 | |||
172 | # For regular reports, it's nice to show them in reverse chronological order |
|
174 | # For regular reports, it's nice to show them in reverse chronological order | |
173 | issues = sorted_by_field(issues, reverse=True) |
|
175 | issues = sorted_by_field(issues, reverse=True) | |
@@ -185,24 +187,35 b' if __name__ == "__main__":' | |||||
185 | print() |
|
187 | print() | |
186 | print("These lists are automatically generated, and may be incomplete or contain duplicates.") |
|
188 | print("These lists are automatically generated, and may be incomplete or contain duplicates.") | |
187 | print() |
|
189 | print() | |
|
190 | ||||
|
191 | ncommits = 0 | |||
|
192 | all_authors = [] | |||
188 | if tag: |
|
193 | if tag: | |
189 | # print git info, in addition to GitHub info: |
|
194 | # print git info, in addition to GitHub info: | |
190 | since_tag = tag+'..' |
|
195 | since_tag = tag+'..' | |
191 | cmd = ['git', 'log', '--oneline', since_tag] |
|
196 | cmd = ['git', 'log', '--oneline', since_tag] | |
192 | ncommits = len(check_output(cmd).splitlines()) |
|
197 | ncommits += len(check_output(cmd).splitlines()) | |
193 |
|
198 | |||
194 | author_cmd = ['git', 'log', '--use-mailmap', "--format=* %aN", since_tag] |
|
199 | author_cmd = ['git', 'log', '--use-mailmap', "--format=* %aN", since_tag] | |
195 |
all_authors |
|
200 | all_authors.extend(check_output(author_cmd).decode('utf-8', 'replace').splitlines()) | |
196 | unique_authors = sorted(set(all_authors), key=lambda s: s.lower()) |
|
201 | ||
197 | print("The following %i authors contributed %i commits." % (len(unique_authors), ncommits)) |
|
202 | pr_authors = [] | |
198 | print() |
|
203 | for pr in pulls: | |
199 | print('\n'.join(unique_authors)) |
|
204 | pr_authors.extend(get_authors(pr)) | |
200 | print() |
|
205 | ncommits = len(pr_authors) + ncommits - len(pulls) | |
201 |
|
206 | author_cmd = ['git', 'check-mailmap'] + pr_authors | ||
|
207 | with_email = check_output(author_cmd).decode('utf-8', 'replace').splitlines() | |||
|
208 | all_authors.extend([ u'* ' + a.split(' <')[0] for a in with_email ]) | |||
|
209 | unique_authors = sorted(set(all_authors), key=lambda s: s.lower()) | |||
|
210 | ||||
|
211 | print("The following %i authors contributed %i commits." % (len(unique_authors), ncommits)) | |||
|
212 | print() | |||
|
213 | print('\n'.join(unique_authors)) | |||
|
214 | ||||
202 | print() |
|
215 | print() | |
203 |
print("We closed |
|
216 | print("We closed %d issues and merged %d pull requests;\n" | |
204 | "this is the full list (generated with the script \n" |
|
217 | "this is the full list (generated with the script \n" | |
205 |
":file:`tools/github_stats.py`):" % ( |
|
218 | ":file:`tools/github_stats.py`):" % (n_pulls, n_issues)) | |
206 | print() |
|
219 | print() | |
207 | print('Pull Requests (%d):\n' % n_pulls) |
|
220 | print('Pull Requests (%d):\n' % n_pulls) | |
208 | report(pulls, show_urls) |
|
221 | report(pulls, show_urls) |
General Comments 0
You need to be logged in to leave comments.
Login now