[tor-commits] [policies/master] Script to determine commit activity

atagar at torproject.org atagar at torproject.org
Sun Oct 1 23:14:19 UTC 2017


commit 3c0e758cabcccc099ad5640deca0f75827342591
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun Oct 1 16:12:57 2017 -0700

    Script to determine commit activity
    
    Simple script that pulls all the repositories listed on
    https://gitweb.torproject.org/ to determine activity in
    the last six months.
---
 scripts/commit_activity.py | 140 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 140 insertions(+)

diff --git a/scripts/commit_activity.py b/scripts/commit_activity.py
new file mode 100644
index 0000000..eeb5e02
--- /dev/null
+++ b/scripts/commit_activity.py
@@ -0,0 +1,140 @@
+import collections
+import os
+import subprocess
+import sys
+
+TMP_DIR = '/tmp/tor_git_repos'
+
+GIT_REPOS = {
+  'anonbib': 'https://git.torproject.org/anonbib.git',
+  'atlas': 'https://git.torproject.org/atlas.git',
+  'bridgedb': 'https://git.torproject.org/bridgedb.git',
+  'builders_gitian-builder': 'https://git.torproject.org/builders/gitian-builder.git',
+  'builders_rbm': 'https://git.torproject.org/builders/rbm.git',
+  'builders_tor-browser-build': 'https://git.torproject.org/builders/tor-browser-build.git',
+  'builders_tor-browser-bundle': 'https://git.torproject.org/builders/tor-browser-bundle.git',
+  'censorship-timeline': 'https://git.torproject.org/censorship-timeline.git',
+  'check': 'https://git.torproject.org/check.git',
+  'chutney': 'https://git.torproject.org/chutney.git',
+  'collector': 'https://git.torproject.org/collector.git',
+  'community_policies': 'https://git.torproject.org/community/policies.git',
+  'company_policies': 'https://git.torproject.org/company/policies.git',
+  'compass': 'https://git.torproject.org/compass.git',
+  'curriculum': 'https://git.torproject.org/curriculum.git',
+  'depictor': 'https://git.torproject.org/depictor.git',
+  'doctor': 'https://git.torproject.org/doctor.git',
+  'erebus': 'https://git.torproject.org/erebus.git',
+  'exonerator': 'https://git.torproject.org/exonerator.git',
+  'flashproxy': 'https://git.torproject.org/flashproxy.git',
+  'fuzzing-corpora': 'https://git.torproject.org/fuzzing-corpora.git',
+  'gettor': 'https://git.torproject.org/gettor.git',
+  'githax': 'https://git.torproject.org/githax.git',
+  'guardfraction': 'https://git.torproject.org/guardfraction.git',
+  'https-everywhere': 'https://git.torproject.org/https-everywhere.git',
+  'metrics-base': 'https://git.torproject.org/metrics-base.git',
+  'metrics-lib': 'https://git.torproject.org/metrics-lib.git',
+  'metrics-tasks': 'https://git.torproject.org/metrics-tasks.git',
+  'metrics-web': 'https://git.torproject.org/metrics-web.git',
+  'nyx': 'https://git.torproject.org/nyx.git',
+  'onionoo': 'https://git.torproject.org/onionoo.git',
+  'ooni-probe': 'https://git.torproject.org/ooni-probe.git',
+  'oonib': 'https://git.torproject.org/ooni/oonib.git',
+  'ooni_reader': 'https://git.torproject.org/ooni/reader.git',
+  'ooni_spec': 'https://git.torproject.org/ooni/spec.git',
+  'ooni_web': 'https://git.torproject.org/ooni/web.git',
+  'orbot': 'https://git.torproject.org/orbot.git',
+  'pluggable-transports_bundle': 'https://git.torproject.org/pluggable-transports/bundle.git',
+  'pluggable-transports_fog': 'https://git.torproject.org/pluggable-transports/fog.git',
+  'pluggable-transports_goptlib': 'https://git.torproject.org/pluggable-transports/goptlib.git',
+  'pluggable-transports_meek': 'https://git.torproject.org/pluggable-transports/meek.git',
+  'pluggable-transports_obfs4': 'https://git.torproject.org/pluggable-transports/obfs4.git',
+  'pluggable-transports_obfsproxy': 'https://git.torproject.org/pluggable-transports/obfsproxy.git',
+  'pluggable-transports_obfsproxy-legacy': 'https://git.torproject.org/pluggable-transports/obfsproxy-legacy.git',
+  'pluggable-transports_pyptlib': 'https://git.torproject.org/pluggable-transports/pyptlib.git',
+  'pluggable-transports_snowflake': 'https://git.torproject.org/pluggable-transports/snowflake.git',
+  'pluggable-transports_websocket': 'https://git.torproject.org/pluggable-transports/websocket.git',
+  'pups': 'https://git.torproject.org/pups.git',
+  'pytorctl': 'https://git.torproject.org/pytorctl.git',
+  'research-web': 'https://git.torproject.org/research-web.git',
+  'stegotorus': 'https://git.torproject.org/stegotorus.git',
+  'stem': 'https://git.torproject.org/stem.git',
+  'support-portal': 'https://git.torproject.org/support-portal.git',
+  'support-tools': 'https://git.torproject.org/support-tools.git',
+  'tech-reports': 'https://git.torproject.org/tech-reports.git',
+  'thandy': 'https://git.torproject.org/thandy.git',
+  'tor': 'https://git.torproject.org/tor.git',
+  'tor-animation': 'https://git.torproject.org/tor-animation.git',
+  'tor-blog': 'https://git.torproject.org/tor-blog.git',
+  'tor-brochure': 'https://git.torproject.org/tor-brochure.git',
+  'tor-browser': 'https://git.torproject.org/tor-browser.git',
+  'tor-browser-spec': 'https://git.torproject.org/tor-browser-spec.git',
+  'sandboxed-tor-browser': 'https://git.torproject.org/tor-browser/sandboxed-tor-browser.git',
+  'user-manual': 'https://git.torproject.org/tor-browser/user-manual.git',
+  'tor-design-2012': 'https://git.torproject.org/tor-design-2012.git',
+  'tor-fw-helper': 'https://git.torproject.org/tor-fw-helper.git',
+  'tor-glossary': 'https://git.torproject.org/tor-glossary.git',
+  'tor-launcher': 'https://git.torproject.org/tor-launcher.git',
+  'tor-manual': 'https://git.torproject.org/tor-manual.git',
+  'tor-messenger-build': 'https://git.torproject.org/tor-messenger-build.git',
+  'tor-ramdisk': 'https://git.torproject.org/tor-ramdisk.git',
+  'torbirdy': 'https://git.torproject.org/torbirdy.git',
+  'torbrowser': 'https://git.torproject.org/torbrowser.git',
+  'torbutton': 'https://git.torproject.org/torbutton.git',
+  'tordnsel': 'https://git.torproject.org/tordnsel.git',
+  'torflow': 'https://git.torproject.org/torflow.git',
+  'torperf': 'https://git.torproject.org/torperf.git',
+  'torsocks': 'https://git.torproject.org/torsocks.git',
+  'torspec': 'https://git.torproject.org/torspec.git',
+  'translation': 'https://git.torproject.org/translation.git',
+  'translation-tools': 'https://git.torproject.org/translation-tools.git',
+  'trunnel': 'https://git.torproject.org/trunnel.git',
+  'weather': 'https://git.torproject.org/weather.git',
+  'webstats': 'https://git.torproject.org/webstats.git',
+}
+
+def call(cmd, cwd = None):
+  if isinstance(cmd, str):
+    cmd = cmd.split()
+
+  process = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE, cwd = cwd)
+  stdout, stderr = process.communicate()
+
+  if process.poll() != 0:
+    print("'%s' failed:\n\nstdout: %s\n\nstderr: %s" % (' '.join(cmd), stdout, stderr))
+    sys.exit(1)
+  else:
+    return stdout.strip()
+
+
+def print_results(title, authors):
+  print('%s:\n' % title)
+
+  if authors:
+    for author, count in sorted(collections.Counter(authors).items(), key = lambda entry: entry[1], reverse = True):
+      print('  %s: %s' % (author, count))
+  else:
+    print('  no activity')
+
+  print('')
+
+
+if not os.path.exists(TMP_DIR):
+  os.mkdir(TMP_DIR)
+
+all_author_emails = []
+
+for name, repo in sorted(GIT_REPOS.items(), key = lambda entry: entry[0]):
+  repo_path = os.path.join(TMP_DIR, name)
+
+  if os.path.exists(repo_path):
+    call('git fetch --all', cwd = repo_path)
+  else:
+    call('git clone --mirror %s %s' % (repo, name), cwd = TMP_DIR)
+
+  author_emails = call(['git', 'log', '--all', '--since', '-6 month', '--format=%an (%ae)'], cwd = repo_path).splitlines()
+  print_results(name, author_emails)
+  all_author_emails += author_emails
+
+
+print_results('Total commit counts', all_author_emails)
+



More information about the tor-commits mailing list