Pep8 compliant

Change-Id: I1638b5c161e92dc864bc4441a5c536f412aba4e1
Signed-off-by: David Caro <dcaroest@redhat.com>
This commit is contained in:
David Caro 2013-10-03 11:37:43 +02:00
parent 6aa42ce112
commit 3f7dbba420
4 changed files with 111 additions and 93 deletions

View File

@ -34,12 +34,16 @@ def main(argv=None):
argv = sys.argv argv = sys.argv
optparser = optparse.OptionParser() optparser = optparse.OptionParser()
optparser.add_option('-p', '--project', default='projects/nova.json', optparser.add_option(
help='JSON file describing the project to generate stats for') '-p', '--project', default='projects/nova.json',
optparser.add_option('-a', '--all', action='store_true', help='JSON file describing the project to generate stats for')
help='Generate stats across all known projects (*.json)') optparser.add_option(
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user') '-a', '--all', action='store_true',
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit') 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', optparser.add_option('-s', '--stable', action='store_true',
help='Include stable branch commits') help='Include stable branch commits')
options, args = optparser.parse_args() options, args = optparser.parse_args()
@ -66,7 +70,8 @@ def main(argv=None):
if approved(patch_set) and not approved(change['patchSets'][-1]): if approved(patch_set) and not approved(change['patchSets'][-1]):
if has_negative_feedback(change['patchSets'][-1]): if has_negative_feedback(change['patchSets'][-1]):
continue 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: for x in approved_and_rebased:
print x print x
@ -76,7 +81,8 @@ def main(argv=None):
def has_negative_feedback(patch_set): def has_negative_feedback(patch_set):
approvals = patch_set.get('approvals', []) approvals = patch_set.get('approvals', [])
for review in 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 True
return False return False

View File

@ -20,8 +20,6 @@ import calendar
import datetime import datetime
import getpass import getpass
import optparse import optparse
import os
import os.path
import sys import sys
import utils import utils
@ -36,7 +34,7 @@ def sec_to_period_string(seconds):
def get_age_of_patch(patch, now_ts): def get_age_of_patch(patch, now_ts):
approvals = patch.get('approvals', []) 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. # The createdOn timestamp on the patch isn't what we want.
# It's when the patch was written, not submitted for review. # 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 # 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 = []
result.append(('Projects', '%s' % [project['name'] result.append(('Projects', '%s' % [project['name']
for project in projects])) for project in projects]))
stats = [] stats = []
stats.append(('Total Open Reviews', '%d' % ( 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 Submitter', '%d' % len(waiting_on_submitter)))
stats.append(('Waiting on Reviewer', '%d' % len(waiting_on_reviewer))) stats.append(('Waiting on Reviewer', '%d' % len(waiting_on_reviewer)))
latest_rev_stats = [] latest_rev_stats = []
latest_rev_stats.append(('Average wait time', '%s' % ( latest_rev_stats.append(('Average wait time', '%s'
average_age(waiting_on_reviewer)))) % (average_age(waiting_on_reviewer))))
latest_rev_stats.append(('Median wait time', '%s' % ( latest_rev_stats.append(('Median wait time', '%s'
median_age(waiting_on_reviewer)))) % (median_age(waiting_on_reviewer))))
latest_rev_stats.append(('Number waiting more than %i days' % latest_rev_stats.append((
options.waiting_more, '%i' % (number_waiting_more_than( 'Number waiting more than %i days' % options.waiting_more,
'%i' % (number_waiting_more_than(
age_sorted, 60 * 60 * 24 * options.waiting_more)))) age_sorted, 60 * 60 * 24 * options.waiting_more))))
stats.append(('Stats since the latest revision', latest_rev_stats)) stats.append(('Stats since the latest revision', latest_rev_stats))
first_rev_stats = [] first_rev_stats = []
first_rev_stats.append(('Average wait time', '%s' % ( first_rev_stats.append(('Average wait time', '%s'
average_age(waiting_on_reviewer, key='age2')))) % (average_age(waiting_on_reviewer, key='age2'))))
first_rev_stats.append(('Median wait time', '%s' % ( first_rev_stats.append(('Median wait time', '%s'
median_age(waiting_on_reviewer, key='age2')))) % (median_age(waiting_on_reviewer, key='age2'))))
stats.append(('Stats since the first revision', first_rev_stats)) stats.append(('Stats since the first revision', first_rev_stats))
last_without_nack_stats = [] last_without_nack_stats = []
last_without_nack_stats.append(('Average wait time', '%s' % ( last_without_nack_stats.append(('Average wait time', '%s'
average_age(waiting_on_reviewer, key='age3')))) % (average_age(waiting_on_reviewer,
last_without_nack_stats.append(('Median wait time', '%s' % ( key='age3'))))
median_age(waiting_on_reviewer, key='age3')))) last_without_nack_stats.append(('Median wait time', '%s'
stats.append(('Stats since the last revision without -1 or -2 (ignoring jenkins)', % (median_age(waiting_on_reviewer,
last_without_nack_stats)) key='age3'))))
stats.append(('Stats since the last revision without -1 or -2 '
'(ignoring jenkins)', last_without_nack_stats))
changes = [] changes = []
for change in age_sorted[:options.longest_waiting]: for change in age_sorted[:options.longest_waiting]:
@ -136,19 +137,19 @@ def gen_stats(projects, waiting_on_reviewer, waiting_on_submitter, options):
changes = [] changes = []
for change in age2_sorted[:options.longest_waiting]: for change in age2_sorted[:options.longest_waiting]:
changes.append('%s %s (%s)' % (sec_to_period_string(change['age2']), changes.append('%s %s (%s)' % (sec_to_period_string(change['age2']),
format_url(change['url'], options), format_url(change['url'], options),
change['subject'])) change['subject']))
stats.append(('Longest waiting reviews (based on first revision)', stats.append(('Longest waiting reviews (based on first revision)',
changes)) changes))
changes = [] changes = []
for change in age3_sorted[:options.longest_waiting]: for change in age3_sorted[:options.longest_waiting]:
changes.append('%s %s (%s)' % (sec_to_period_string(change['age3']), changes.append('%s %s (%s)' % (sec_to_period_string(change['age3']),
format_url(change['url'], options), format_url(change['url'], options),
change['subject'])) change['subject']))
stats.append(('Longest waiting reviews (based on oldest rev without nack, ignoring jenkins)', stats.append(('Longest waiting reviews (based on oldest rev without nack, '
changes)) 'ignoring jenkins)', changes))
result.append(stats) result.append(stats)
@ -231,20 +232,28 @@ def main(argv=None):
argv = sys.argv argv = sys.argv
optparser = optparse.OptionParser() optparser = optparse.OptionParser()
optparser.add_option('-p', '--project', default='projects/nova.json', optparser.add_option(
help='JSON file describing the project to generate stats for') '-p', '--project', default='projects/nova.json',
optparser.add_option('-a', '--all', action='store_true', help='JSON file describing the project to generate stats for')
help='Generate stats across all known projects (*.json)') optparser.add_option(
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user') '-a', '--all', action='store_true',
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit') help='Generate stats across all known projects (*.json)')
optparser.add_option('-s', '--stable', action='store_true', optparser.add_option(
help='Include stable branch commits') '-u', '--user', default=getpass.getuser(), help='gerrit user')
optparser.add_option('-l', '--longest-waiting', type='int', default=5, optparser.add_option(
help='Show n changesets that have waited the longest)') '-k', '--key', default=None, help='ssh key for gerrit')
optparser.add_option('-m', '--waiting-more', type='int', default=7, optparser.add_option(
help='Show number of changesets that have waited more than n days)') '-s', '--stable', action='store_true',
optparser.add_option('-H', '--html', action='store_true', help='Include stable branch commits')
help='Use HTML output instead of plain text') 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() options, args = optparser.parse_args()
@ -255,7 +264,7 @@ def main(argv=None):
sys.exit(1) sys.exit(1)
changes = utils.get_changes(projects, options.user, options.key, changes = utils.get_changes(projects, options.user, options.key,
only_open=True) only_open=True)
waiting_on_submitter = [] waiting_on_submitter = []
waiting_on_reviewer = [] waiting_on_reviewer = []
@ -274,7 +283,7 @@ def main(argv=None):
latest_patch = change['patchSets'][-1] latest_patch = change['patchSets'][-1]
waiting_for_review = True waiting_for_review = True
approvals = latest_patch.get('approvals', []) approvals = latest_patch.get('approvals', [])
approvals.sort(key=lambda a:a['grantedOn']) approvals.sort(key=lambda a: a['grantedOn'])
for review in approvals: for review in approvals:
if review['type'] not in ('CRVW', 'VRIF'): if review['type'] not in ('CRVW', 'VRIF'):
continue continue

View File

@ -16,16 +16,10 @@
# under the License. # under the License.
import calendar import calendar
import datetime import datetime
import getpass import getpass
import glob
import json
import optparse import optparse
import os
import os.path
from pprint import pprint
import prettytable import prettytable
import sys import sys
@ -42,8 +36,8 @@ def process_patchset(project, patchset, reviewers, ts):
latest_core_pos_vote = 0 latest_core_pos_vote = 0
for review in patchset.get('approvals', []): for review in patchset.get('approvals', []):
if review['type'] != 'CRVW': if review['type'] != 'CRVW':
# Only count code reviews. Don't add another for Approved, which is # Only count code reviews. Don't add another for Approved, which
# type 'APRV' # is type 'APRV'
continue continue
if review['by'].get('username', 'unknown') not in project['core-team']: if review['by'].get('username', 'unknown') not in project['core-team']:
# Only checking for disagreements from core team members # Only checking for disagreements from core team members
@ -60,13 +54,13 @@ def process_patchset(project, patchset, reviewers, ts):
continue continue
if review['type'] != 'CRVW': if review['type'] != 'CRVW':
# Only count code reviews. Don't add another for Approved, which is # Only count code reviews. Don't add another for Approved, which
# type 'APRV' # is type 'APRV'
continue continue
reviewer = review['by'].get('username', 'unknown') reviewer = review['by'].get('username', 'unknown')
reviewers.setdefault(reviewer, 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].setdefault('disagreements', 0)
reviewers[reviewer]['total'] = reviewers[reviewer].get('total', 0) + 1 reviewers[reviewer]['total'] = reviewers[reviewer].get('total', 0) + 1
cur = reviewers[reviewer]['votes'][review['value']] cur = reviewers[reviewer]['votes'][review['value']]
@ -90,14 +84,19 @@ def main(argv=None):
argv = sys.argv argv = sys.argv
optparser = optparse.OptionParser() optparser = optparse.OptionParser()
optparser.add_option('-p', '--project', default='projects/nova.json', optparser.add_option(
help='JSON file describing the project to generate stats for') '-p', '--project', default='projects/nova.json',
optparser.add_option('-a', '--all', action='store_true', help='JSON file describing the project to generate stats for')
help='Generate stats across all known projects (*.json)') optparser.add_option(
optparser.add_option('-d', '--days', type='int', default=14, '-a', '--all', action='store_true',
help='Number of days to consider') help='Generate stats across all known projects (*.json)')
optparser.add_option('-u', '--user', default=getpass.getuser(), help='gerrit user') optparser.add_option(
optparser.add_option('-k', '--key', default=None, help='ssh key for gerrit') '-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() options, args = optparser.parse_args()
@ -120,21 +119,22 @@ def main(argv=None):
reviewers = [(v, k) for k, v in reviewers.iteritems() reviewers = [(v, k) for k, v in reviewers.iteritems()
if k.lower() not in ('jenkins', 'smokestack')] 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: if options.all:
print 'Reviews for the last %d days in projects: %s' % (options.days, print 'Reviews for the last %d days in projects: %s' \
[project['name'] for project in projects]) % (options.days, [project['name'] for project in projects])
else: 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: if options.all:
print '** -- Member of at least one core reviewer team' print '** -- Member of at least one core reviewer team'
else: else:
print '** -- %s-core team member' % projects[0]['name'] print '** -- %s-core team member' % projects[0]['name']
table = prettytable.PrettyTable( table = prettytable.PrettyTable(
('Reviewer', ('Reviewer',
'Reviews -2 -1 +1 +2 +/- %', 'Reviews -2 -1 +1 +2 +/- %',
'Disagreements*')) 'Disagreements*'))
total = 0 total = 0
for k, v in reviewers: for k, v in reviewers:
in_core_team = False in_core_team = False
@ -146,9 +146,10 @@ def main(argv=None):
plus = float(k['votes']['2'] + k['votes']['1']) plus = float(k['votes']['2'] + k['votes']['1'])
minus = float(k['votes']['-2'] + k['votes']['-1']) minus = float(k['votes']['-2'] + k['votes']['-1'])
ratio = (plus / (plus + minus)) * 100 ratio = (plus / (plus + minus)) * 100
r = '%7d %3d %3d %3d %3d %5.1f%%' % (k['total'], r = '%7d %3d %3d %3d %3d %5.1f%%' % (
k['votes']['-2'], k['votes']['-1'], k['total'], k['votes']['-2'],
k['votes']['1'], k['votes']['2'], ratio) k['votes']['-1'], k['votes']['1'],
k['votes']['2'], ratio)
dratio = ((float(k['disagreements']) / plus) * 100) if plus else 0.0 dratio = ((float(k['disagreements']) / plus) * 100) if plus else 0.0
d = '%3d (%5.1f%%)' % (k['disagreements'], dratio) d = '%3d (%5.1f%%)' % (k['disagreements'], dratio)
table.add_row((name, r, d)) table.add_row((name, r, d))

View File

@ -26,13 +26,15 @@ import utils
def main(): def main():
parser = ArgumentParser( parser = ArgumentParser(
description="Get reviews for open bugs against a milestone") description="Get reviews for open bugs against a milestone")
parser.add_argument('-p', '--project', default='projects/nova.json', parser.add_argument(
help='JSON file describing the project to generate stats for') '-p', '--project', default='projects/nova.json',
parser.add_argument('-m', '--milestone', default='', help='JSON file describing the project to generate stats for')
help='Only show bugs targeted to a specified milestone') parser.add_argument(
parser.add_argument('-u', '--user', default=getpass.getuser(), '-m', '--milestone', default='',
help='gerrit user') 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') parser.add_argument('-k', '--key', default=None, help='ssh key for gerrit')
args = parser.parse_args() args = parser.parse_args()
@ -79,15 +81,15 @@ def main():
milestones[milestone].append((change['url'], bugid)) milestones[milestone].append((change['url'], bugid))
print 'Reviews for bugs grouped by milestone for project: %s\n' % ( print 'Reviews for bugs grouped by milestone for project: %s\n' % (
project_name) project_name)
for milestone, reviews in milestones.items(): for milestone, reviews in milestones.items():
if args.milestone and milestone != args.milestone: if args.milestone and milestone != args.milestone:
continue continue
print 'Milestone: %s' % milestone print 'Milestone: %s' % milestone
for review, bugid in reviews: for review, bugid in reviews:
print '--> %s -- https://bugs.launchpad.net/%s/+bug/%s' % (review, print '--> %s -- https://bugs.launchpad.net/%s/+bug/%s' \
project_name, bugid) % (review, project_name, bugid)
print print
if __name__ == '__main__': if __name__ == '__main__':