Pep8 compliant
Change-Id: I1638b5c161e92dc864bc4441a5c536f412aba4e1 Signed-off-by: David Caro <dcaroest@redhat.com>
This commit is contained in:
parent
6aa42ce112
commit
3f7dbba420
@ -34,12 +34,16 @@ def main(argv=None):
|
||||
argv = sys.argv
|
||||
|
||||
optparser = optparse.OptionParser()
|
||||
optparser.add_option('-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option('-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit')
|
||||
optparser.add_option(
|
||||
'-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option(
|
||||
'-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option(
|
||||
'-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option(
|
||||
'-k', '--key', default=None, help='ssh key for gerrit')
|
||||
optparser.add_option('-s', '--stable', action='store_true',
|
||||
help='Include stable branch commits')
|
||||
options, args = optparser.parse_args()
|
||||
@ -66,7 +70,8 @@ def main(argv=None):
|
||||
if approved(patch_set) and not approved(change['patchSets'][-1]):
|
||||
if has_negative_feedback(change['patchSets'][-1]):
|
||||
continue
|
||||
approved_and_rebased.add("%s %s" % (change['url'], change['subject']))
|
||||
approved_and_rebased.add("%s %s" % (change['url'],
|
||||
change['subject']))
|
||||
|
||||
for x in approved_and_rebased:
|
||||
print x
|
||||
@ -76,7 +81,8 @@ def main(argv=None):
|
||||
def has_negative_feedback(patch_set):
|
||||
approvals = patch_set.get('approvals', [])
|
||||
for review in approvals:
|
||||
if review['type'] in ('CRVW','VRIF') and review['value'] in ('-1', '-2'):
|
||||
if review['type'] in ('CRVW', 'VRIF') \
|
||||
and review['value'] in ('-1', '-2'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
101
openreviews.py
101
openreviews.py
@ -20,8 +20,6 @@ import calendar
|
||||
import datetime
|
||||
import getpass
|
||||
import optparse
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
import utils
|
||||
@ -36,7 +34,7 @@ def sec_to_period_string(seconds):
|
||||
|
||||
def get_age_of_patch(patch, now_ts):
|
||||
approvals = patch.get('approvals', [])
|
||||
approvals.sort(key=lambda a:a['grantedOn'])
|
||||
approvals.sort(key=lambda a: a['grantedOn'])
|
||||
# The createdOn timestamp on the patch isn't what we want.
|
||||
# It's when the patch was written, not submitted for review.
|
||||
# The next best thing in the data we have is the time of the
|
||||
@ -94,37 +92,40 @@ def gen_stats(projects, waiting_on_reviewer, waiting_on_submitter, options):
|
||||
|
||||
result = []
|
||||
result.append(('Projects', '%s' % [project['name']
|
||||
for project in projects]))
|
||||
for project in projects]))
|
||||
stats = []
|
||||
stats.append(('Total Open Reviews', '%d' % (
|
||||
len(waiting_on_reviewer) + len(waiting_on_submitter))))
|
||||
len(waiting_on_reviewer) + len(waiting_on_submitter))))
|
||||
stats.append(('Waiting on Submitter', '%d' % len(waiting_on_submitter)))
|
||||
stats.append(('Waiting on Reviewer', '%d' % len(waiting_on_reviewer)))
|
||||
|
||||
latest_rev_stats = []
|
||||
latest_rev_stats.append(('Average wait time', '%s' % (
|
||||
average_age(waiting_on_reviewer))))
|
||||
latest_rev_stats.append(('Median wait time', '%s' % (
|
||||
median_age(waiting_on_reviewer))))
|
||||
latest_rev_stats.append(('Number waiting more than %i days' %
|
||||
options.waiting_more, '%i' % (number_waiting_more_than(
|
||||
latest_rev_stats.append(('Average wait time', '%s'
|
||||
% (average_age(waiting_on_reviewer))))
|
||||
latest_rev_stats.append(('Median wait time', '%s'
|
||||
% (median_age(waiting_on_reviewer))))
|
||||
latest_rev_stats.append((
|
||||
'Number waiting more than %i days' % options.waiting_more,
|
||||
'%i' % (number_waiting_more_than(
|
||||
age_sorted, 60 * 60 * 24 * options.waiting_more))))
|
||||
stats.append(('Stats since the latest revision', latest_rev_stats))
|
||||
|
||||
first_rev_stats = []
|
||||
first_rev_stats.append(('Average wait time', '%s' % (
|
||||
average_age(waiting_on_reviewer, key='age2'))))
|
||||
first_rev_stats.append(('Median wait time', '%s' % (
|
||||
median_age(waiting_on_reviewer, key='age2'))))
|
||||
first_rev_stats.append(('Average wait time', '%s'
|
||||
% (average_age(waiting_on_reviewer, key='age2'))))
|
||||
first_rev_stats.append(('Median wait time', '%s'
|
||||
% (median_age(waiting_on_reviewer, key='age2'))))
|
||||
stats.append(('Stats since the first revision', first_rev_stats))
|
||||
|
||||
last_without_nack_stats = []
|
||||
last_without_nack_stats.append(('Average wait time', '%s' % (
|
||||
average_age(waiting_on_reviewer, key='age3'))))
|
||||
last_without_nack_stats.append(('Median wait time', '%s' % (
|
||||
median_age(waiting_on_reviewer, key='age3'))))
|
||||
stats.append(('Stats since the last revision without -1 or -2 (ignoring jenkins)',
|
||||
last_without_nack_stats))
|
||||
last_without_nack_stats.append(('Average wait time', '%s'
|
||||
% (average_age(waiting_on_reviewer,
|
||||
key='age3'))))
|
||||
last_without_nack_stats.append(('Median wait time', '%s'
|
||||
% (median_age(waiting_on_reviewer,
|
||||
key='age3'))))
|
||||
stats.append(('Stats since the last revision without -1 or -2 '
|
||||
'(ignoring jenkins)', last_without_nack_stats))
|
||||
|
||||
changes = []
|
||||
for change in age_sorted[:options.longest_waiting]:
|
||||
@ -136,19 +137,19 @@ def gen_stats(projects, waiting_on_reviewer, waiting_on_submitter, options):
|
||||
|
||||
changes = []
|
||||
for change in age2_sorted[:options.longest_waiting]:
|
||||
changes.append('%s %s (%s)' % (sec_to_period_string(change['age2']),
|
||||
format_url(change['url'], options),
|
||||
change['subject']))
|
||||
changes.append('%s %s (%s)' % (sec_to_period_string(change['age2']),
|
||||
format_url(change['url'], options),
|
||||
change['subject']))
|
||||
stats.append(('Longest waiting reviews (based on first revision)',
|
||||
changes))
|
||||
changes))
|
||||
|
||||
changes = []
|
||||
for change in age3_sorted[:options.longest_waiting]:
|
||||
changes.append('%s %s (%s)' % (sec_to_period_string(change['age3']),
|
||||
format_url(change['url'], options),
|
||||
change['subject']))
|
||||
stats.append(('Longest waiting reviews (based on oldest rev without nack, ignoring jenkins)',
|
||||
changes))
|
||||
changes.append('%s %s (%s)' % (sec_to_period_string(change['age3']),
|
||||
format_url(change['url'], options),
|
||||
change['subject']))
|
||||
stats.append(('Longest waiting reviews (based on oldest rev without nack, '
|
||||
'ignoring jenkins)', changes))
|
||||
|
||||
result.append(stats)
|
||||
|
||||
@ -231,20 +232,28 @@ def main(argv=None):
|
||||
argv = sys.argv
|
||||
|
||||
optparser = optparse.OptionParser()
|
||||
optparser.add_option('-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option('-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit')
|
||||
optparser.add_option('-s', '--stable', action='store_true',
|
||||
help='Include stable branch commits')
|
||||
optparser.add_option('-l', '--longest-waiting', type='int', default=5,
|
||||
help='Show n changesets that have waited the longest)')
|
||||
optparser.add_option('-m', '--waiting-more', type='int', default=7,
|
||||
help='Show number of changesets that have waited more than n days)')
|
||||
optparser.add_option('-H', '--html', action='store_true',
|
||||
help='Use HTML output instead of plain text')
|
||||
optparser.add_option(
|
||||
'-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option(
|
||||
'-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option(
|
||||
'-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option(
|
||||
'-k', '--key', default=None, help='ssh key for gerrit')
|
||||
optparser.add_option(
|
||||
'-s', '--stable', action='store_true',
|
||||
help='Include stable branch commits')
|
||||
optparser.add_option(
|
||||
'-l', '--longest-waiting', type='int', default=5,
|
||||
help='Show n changesets that have waited the longest)')
|
||||
optparser.add_option(
|
||||
'-m', '--waiting-more', type='int', default=7,
|
||||
help='Show number of changesets that have waited more than n days)')
|
||||
optparser.add_option(
|
||||
'-H', '--html', action='store_true',
|
||||
help='Use HTML output instead of plain text')
|
||||
|
||||
options, args = optparser.parse_args()
|
||||
|
||||
@ -255,7 +264,7 @@ def main(argv=None):
|
||||
sys.exit(1)
|
||||
|
||||
changes = utils.get_changes(projects, options.user, options.key,
|
||||
only_open=True)
|
||||
only_open=True)
|
||||
|
||||
waiting_on_submitter = []
|
||||
waiting_on_reviewer = []
|
||||
@ -274,7 +283,7 @@ def main(argv=None):
|
||||
latest_patch = change['patchSets'][-1]
|
||||
waiting_for_review = True
|
||||
approvals = latest_patch.get('approvals', [])
|
||||
approvals.sort(key=lambda a:a['grantedOn'])
|
||||
approvals.sort(key=lambda a: a['grantedOn'])
|
||||
for review in approvals:
|
||||
if review['type'] not in ('CRVW', 'VRIF'):
|
||||
continue
|
||||
|
59
reviewers.py
59
reviewers.py
@ -16,16 +16,10 @@
|
||||
# under the License.
|
||||
|
||||
|
||||
|
||||
import calendar
|
||||
import datetime
|
||||
import getpass
|
||||
import glob
|
||||
import json
|
||||
import optparse
|
||||
import os
|
||||
import os.path
|
||||
from pprint import pprint
|
||||
import prettytable
|
||||
import sys
|
||||
|
||||
@ -42,8 +36,8 @@ def process_patchset(project, patchset, reviewers, ts):
|
||||
latest_core_pos_vote = 0
|
||||
for review in patchset.get('approvals', []):
|
||||
if review['type'] != 'CRVW':
|
||||
# Only count code reviews. Don't add another for Approved, which is
|
||||
# type 'APRV'
|
||||
# Only count code reviews. Don't add another for Approved, which
|
||||
# is type 'APRV'
|
||||
continue
|
||||
if review['by'].get('username', 'unknown') not in project['core-team']:
|
||||
# Only checking for disagreements from core team members
|
||||
@ -60,13 +54,13 @@ def process_patchset(project, patchset, reviewers, ts):
|
||||
continue
|
||||
|
||||
if review['type'] != 'CRVW':
|
||||
# Only count code reviews. Don't add another for Approved, which is
|
||||
# type 'APRV'
|
||||
# Only count code reviews. Don't add another for Approved, which
|
||||
# is type 'APRV'
|
||||
continue
|
||||
|
||||
reviewer = review['by'].get('username', 'unknown')
|
||||
reviewers.setdefault(reviewer,
|
||||
{'votes': {'-2': 0, '-1': 0, '1': 0, '2': 0}})
|
||||
{'votes': {'-2': 0, '-1': 0, '1': 0, '2': 0}})
|
||||
reviewers[reviewer].setdefault('disagreements', 0)
|
||||
reviewers[reviewer]['total'] = reviewers[reviewer].get('total', 0) + 1
|
||||
cur = reviewers[reviewer]['votes'][review['value']]
|
||||
@ -90,14 +84,19 @@ def main(argv=None):
|
||||
argv = sys.argv
|
||||
|
||||
optparser = optparse.OptionParser()
|
||||
optparser.add_option('-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option('-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option('-d', '--days', type='int', default=14,
|
||||
help='Number of days to consider')
|
||||
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit')
|
||||
optparser.add_option(
|
||||
'-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
optparser.add_option(
|
||||
'-a', '--all', action='store_true',
|
||||
help='Generate stats across all known projects (*.json)')
|
||||
optparser.add_option(
|
||||
'-d', '--days', type='int', default=14,
|
||||
help='Number of days to consider')
|
||||
optparser.add_option(
|
||||
'-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
optparser.add_option(
|
||||
'-k', '--key', default=None, help='ssh key for gerrit')
|
||||
|
||||
options, args = optparser.parse_args()
|
||||
|
||||
@ -120,21 +119,22 @@ def main(argv=None):
|
||||
|
||||
reviewers = [(v, k) for k, v in reviewers.iteritems()
|
||||
if k.lower() not in ('jenkins', 'smokestack')]
|
||||
reviewers.sort(reverse=True, key=lambda r:r[0]['total'])
|
||||
reviewers.sort(reverse=True, key=lambda r: r[0]['total'])
|
||||
|
||||
if options.all:
|
||||
print 'Reviews for the last %d days in projects: %s' % (options.days,
|
||||
[project['name'] for project in projects])
|
||||
print 'Reviews for the last %d days in projects: %s' \
|
||||
% (options.days, [project['name'] for project in projects])
|
||||
else:
|
||||
print 'Reviews for the last %d days in %s' % (options.days, projects[0]['name'])
|
||||
print 'Reviews for the last %d days in %s' \
|
||||
% (options.days, projects[0]['name'])
|
||||
if options.all:
|
||||
print '** -- Member of at least one core reviewer team'
|
||||
else:
|
||||
print '** -- %s-core team member' % projects[0]['name']
|
||||
table = prettytable.PrettyTable(
|
||||
('Reviewer',
|
||||
'Reviews -2 -1 +1 +2 +/- %',
|
||||
'Disagreements*'))
|
||||
('Reviewer',
|
||||
'Reviews -2 -1 +1 +2 +/- %',
|
||||
'Disagreements*'))
|
||||
total = 0
|
||||
for k, v in reviewers:
|
||||
in_core_team = False
|
||||
@ -146,9 +146,10 @@ def main(argv=None):
|
||||
plus = float(k['votes']['2'] + k['votes']['1'])
|
||||
minus = float(k['votes']['-2'] + k['votes']['-1'])
|
||||
ratio = (plus / (plus + minus)) * 100
|
||||
r = '%7d %3d %3d %3d %3d %5.1f%%' % (k['total'],
|
||||
k['votes']['-2'], k['votes']['-1'],
|
||||
k['votes']['1'], k['votes']['2'], ratio)
|
||||
r = '%7d %3d %3d %3d %3d %5.1f%%' % (
|
||||
k['total'], k['votes']['-2'],
|
||||
k['votes']['-1'], k['votes']['1'],
|
||||
k['votes']['2'], ratio)
|
||||
dratio = ((float(k['disagreements']) / plus) * 100) if plus else 0.0
|
||||
d = '%3d (%5.1f%%)' % (k['disagreements'], dratio)
|
||||
table.add_row((name, r, d))
|
||||
|
@ -26,13 +26,15 @@ import utils
|
||||
|
||||
def main():
|
||||
parser = ArgumentParser(
|
||||
description="Get reviews for open bugs against a milestone")
|
||||
parser.add_argument('-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
parser.add_argument('-m', '--milestone', default='',
|
||||
help='Only show bugs targeted to a specified milestone')
|
||||
parser.add_argument('-u', '--user', default=getpass.getuser(),
|
||||
help='gerrit user')
|
||||
description="Get reviews for open bugs against a milestone")
|
||||
parser.add_argument(
|
||||
'-p', '--project', default='projects/nova.json',
|
||||
help='JSON file describing the project to generate stats for')
|
||||
parser.add_argument(
|
||||
'-m', '--milestone', default='',
|
||||
help='Only show bugs targeted to a specified milestone')
|
||||
parser.add_argument(
|
||||
'-u', '--user', default=getpass.getuser(), help='gerrit user')
|
||||
parser.add_argument('-k', '--key', default=None, help='ssh key for gerrit')
|
||||
|
||||
args = parser.parse_args()
|
||||
@ -79,15 +81,15 @@ def main():
|
||||
milestones[milestone].append((change['url'], bugid))
|
||||
|
||||
print 'Reviews for bugs grouped by milestone for project: %s\n' % (
|
||||
project_name)
|
||||
project_name)
|
||||
|
||||
for milestone, reviews in milestones.items():
|
||||
if args.milestone and milestone != args.milestone:
|
||||
continue
|
||||
print 'Milestone: %s' % milestone
|
||||
for review, bugid in reviews:
|
||||
print '--> %s -- https://bugs.launchpad.net/%s/+bug/%s' % (review,
|
||||
project_name, bugid)
|
||||
print '--> %s -- https://bugs.launchpad.net/%s/+bug/%s' \
|
||||
% (review, project_name, bugid)
|
||||
print
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
Loading…
Reference in New Issue
Block a user