#!/usr/bin/env python import argparse import datetime import jinja2 import logging import os import pprint import re import subprocess import teamanalysis.config import teamanalysis.git import teamanalysis.repos import teamanalysis.time import webbrowser LOGGER = logging.getLogger('overview-by-date') def _get_abspath(repo): return '/Users/eliribble/src/teamanalysis/repos/{}/'.format(repo) def _get_commit_count(repo, start, end, my_email): abspath = _get_abspath(repo) os.chdir(abspath) command = ['git', 'checkout', 'master'] subprocess.check_output(command, stderr=subprocess.STDOUT) command = [ 'git', 'log', '--pretty=format:"%h %aI %aE"', '--after={}'.format(start.isoformat()), '--before={}'.format(end.isoformat())] LOGGER.debug(" ".join(command)) output = subprocess.check_output(command) lines = output.split('\n') total = len(lines) if output else 0 my_lines = [line for line in lines if my_email in line] mine = len(my_lines) return {'total': total, 'mine': mine} def _get_commit_sha_by_date(repo, timepoint): abspath = _get_abspath(repo) os.chdir(abspath) command = [ 'git', 'rev-list', '-n', '1', '--before="{}"'.format(timepoint.date().isoformat()), 'master', '--', ] LOGGER.debug("%s", ' '.join(command)) output = subprocess.check_output(command) output = output.strip() LOGGER.debug("%s: %s", ' '.join(command), output) return output def _git_checkout_by_date(repo, timepoint): abspath = _get_abspath(repo) commit = _get_commit_sha_by_date(repo, timepoint) os.chdir(abspath) command = [ 'git', 'checkout', commit, ] try: output = subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: LOGGER.warning("Failed to execute '%s' in %s", command, abspath) return '' LOGGER.debug("Checked out %s at %s", repo, timepoint.date().isoformat()) return output TEST_FUNCTION_PATTERN = re.compile(r'\s+<Function') def _count_tests(repo): abspath = _get_abspath(repo) os.chdir(abspath) command = [ os.path.join(abspath, 've', 'bin', 'python'), '/usr/local/bin/py.test', '--collect-only' ] LOGGER.debug(" ".join(command)) try: output = subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError: LOGGER.info("Failed to call py.test for %s", repo) return 0 count = 0 for line in output.split('\n'): if TEST_FUNCTION_PATTERN.match(line): count += 1 LOGGER.debug("Counted %d tests for %s", count, repo) return count def _get_test_count(repo, end): abspath = _get_abspath(repo) _git_checkout_by_date(repo, end) return _count_tests(repo) def _show_summary(timepoint, my_email): start, end = teamanalysis.time.get_checkpoint(timepoint) LOGGER.debug("Working %s to %s for %s", start, end, timepoint) results = {} for repo in teamanalysis.repos.REPOSITORIES: commits = _get_commit_count(repo, start, end, my_email) tests = _get_test_count(repo, end) results[repo] = { 'commits' : commits, 'tests' : tests, } #print("{0:<30}: {1}".format(repo, results[repo])) #pprint.pprint({k: v['tests'] for k, v in results.items()}) #pprint.pprint({k: v['commits'] for k, v in results.items()}) totals = { 'all_commits' : sum([result['commits']['total'] for result in results.values()]), 'my_commits' : sum([result['commits']['mine'] for result in results.values()]), 'tests' : sum([result['tests'] for result in results.values() if result['tests']]), } print("\t".join(map(str, [start.date().isoformat(), end.date().isoformat(), totals['all_commits'], totals['my_commits'], totals['tests']]))) def main(): logging.basicConfig() LOGGER.setLevel(logging.INFO) #LOGGER.setLevel(logging.DEBUG) config = teamanalysis.config.get() timepoint = datetime.datetime(2013, 12, 30, 0, 0, 1) now = datetime.datetime.utcnow() while timepoint < now + datetime.timedelta(days=7): _show_summary(timepoint, config['my_email']) timepoint = timepoint + datetime.timedelta(days=7) if __name__ == '__main__': main()