From 73d58516f72e8d9d10b6d3e2120214b31a43a693 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Thu, 14 Jul 2016 15:40:42 +0200 Subject: [PATCH] Update thresholds for active reviewers We've been using 30 as the threshold to determine when reviewers are active in a project. This commit expands the threshold to include also reviewers that have reviewed at least 2% of the proposed patches. Change-Id: I256a031b8a9b1e5b8635f626c0a13e0d06648256 --- tools/teamstats.py | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/tools/teamstats.py b/tools/teamstats.py index d2b4257d8..ca4a7f26d 100644 --- a/tools/teamstats.py +++ b/tools/teamstats.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +import functools import os import sys import time @@ -29,20 +30,50 @@ s = requests.session() six_months = int(time.time() - 30*6*24*60*60) # 6 months ago +# NOTE(flaper87): This value affects both, single-vendor and diverse-affiliation +# tags and it's been tuned to a reasonable enough threshold to measure reviews +# activeness. Changes to this value must be discussed separately. +MIN_PERCENTAGE_REVIEWS = 0.02 # 2% MIN_REVIEWS = 30 MIN_COMMITS = 6 +def _memoize(func): + cache = {} + + @functools.wraps(func) + def memoized(*args, **kwargs): + key = (args, tuple(kwargs.items())) + try: + return cache[key] + except KeyError: + cache[key] = func(*args, **kwargs) + return cache[key] + return memoized + + +@_memoize +def _get_number_of_commits(group, start_date=six_months): + commits = s.get('http://stackalytics.com/api/' + '1.0/stats/companies?metric=commits&release=all' + '&project_type=all&module=%s&start_date=%s' + % (group, start_date)).json() + return sum([company['metric'] for company in commits['stats']]) + + +@_memoize def get_team_size_stats(team): team_stats = {} group = "%s-group" % team.lower() + commits_total = _get_number_of_commits(group) + min_percent = int(commits_total * MIN_PERCENTAGE_REVIEWS) reviews = s.get('http://stackalytics.com/api/' '1.0/stats/engineers?metric=marks&release=all' '&start_date=%s&project_type=all' '&module=%s' % (six_months, group)).json() team_stats['active_reviewers'] = 0 for eng in reviews['stats']: - if eng['metric'] >= MIN_REVIEWS: + if eng['metric'] >= MIN_REVIEWS or eng['metric'] >= min_percent: team_stats['active_reviewers'] += 1 team_stats['active_committers'] = 0 @@ -57,8 +88,12 @@ def get_team_size_stats(team): return team_stats +@_memoize def get_core_reviews_by_company(group): # reviews by individual + commits_total = _get_number_of_commits(group) + min_percent = int(commits_total * MIN_PERCENTAGE_REVIEWS) + reviews = s.get('http://stackalytics.com/api/' '1.0/stats/engineers?metric=marks&release=all' '&start_date=%s&project_type=all' @@ -74,11 +109,14 @@ def get_core_reviews_by_company(group): % (group, eng['id'], six_months)).json()['stats'][0]['id'] companies.setdefault(company, {'reviewers': 0, 'reviews': 0}) - companies[company]['reviews'] += eng['metric'] - companies[company]['reviewers'] += 1 + + if eng['metric'] >= MIN_REVIEWS or eng['metric'] >= min_percent: + companies[company]['reviews'] += eng['metric'] + companies[company]['reviewers'] += 1 + return companies - +@_memoize def get_diversity_stats(project): team_stats = {} # commits by company