Skip to content

Instantly share code, notes, and snippets.

@ralphbean
Created August 4, 2015 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ralphbean/2787025c1ee164abb731 to your computer and use it in GitHub Desktop.
Save ralphbean/2787025c1ee164abb731 to your computer and use it in GitHub Desktop.
""" Calculate "dev to release" leadtime.
Prints out statistics about the time between the first commit of a new feature
and the tag where that feature gets released.
Ideally, we'd like to compute the time between first commit and deployment to
production, but we don't have an easy way to reliably access logs of when
things were deployed against when they were committed in git.
A quick script for my talk on technical debt at Flock 2015.
:Author: Ralph Bean
:License: LGPLv2+
Example output::
00136296 trac-fedmsg-plugin 1 day, 13:51:36.750000
00206261 pagure 2 days, 9:17:41.111111
00245100 mote 2 days, 20:05:00.692308
00352005 copr 4 days, 1:46:45.962121
00372609 fedmsg-atomic-composer 4 days, 7:30:09.333333
00451242 pkgdb2 5 days, 5:20:42.313433
00481212 fedora-releng-dash 5 days, 13:40:12.142857
00617381 anitya 7 days, 3:29:41
00849204 fedmsg_meta_fedora_infrastructure 9 days, 19:53:24.013699
01156537 fmn.rules 13 days, 9:15:37.148148
01202462 mirrormanager2 13 days, 22:01:02.111111
01238799 tahrir-api 14 days, 8:06:39.736842
01360000 fmn.lib 15 days, 17:46:40.095238
01441767 fmn.consumer 16 days, 16:29:27.869565
01567893 the-new-hotness 18 days, 3:31:33.181818
01672438 datanommer 19 days, 8:33:58.333333
01677784 github2fedmsg 19 days, 10:03:04.500000
01709390 fedocal 19 days, 18:49:50.424242
01748422 fmn.web 20 days, 5:40:22.913043
02043473 fedmsg 23 days, 15:37:53.052632
02254484 pkgwat.api 26 days, 2:14:44.500000
02759818 tahrir 31 days, 22:36:58.354839
02899894 gnome-shell-extension-fedmsg 33 days, 13:31:34.200000
02955532 blockerbugs 34 days, 4:58:52.421053
03284851 bodhi 38 days, 0:27:31.955224
03343189 fedora-tagger 38 days, 16:39:49.388889
03578008 pyrasite 41 days, 9:53:28.666667
03621579 resultsdb_api 41 days, 21:59:39
03759724 fas 43 days, 12:22:04.271186
03798244 packagedb-cli 43 days, 23:04:04.608696
03929364 bugzilla2fedmsg 45 days, 11:29:24.250000
04025004 resultsdb_frontend 46 days, 14:03:24.428571
04462099 datagrepper 51 days, 15:28:19.769231
04478169 resultsdb 51 days, 19:56:09.142857
04558950 nuancier 52 days, 18:22:30.437500
05383642 fedbadges 62 days, 7:27:22.909091
05793006 python-fedora 67 days, 1:10:06.916667
05825923 supybot-fedora 67 days, 10:18:43.333333
07118009 pkgwat.cli 82 days, 9:13:29
07859622 koji 90 days, 23:13:42.592593
08186664 sigul 94 days, 18:04:24.888889
09974324 fedora-packages 115 days, 10:38:44.875000
15651235 kitchen 181 days, 3:33:55.250000
"""
import datetime
import os
import sys
import arrow
import pygit2
project = sys.argv[-1]
repo = pygit2.Repository(os.path.expanduser("~/devel/" + project))
verbose = False
refs = repo.listall_references()
prefix = 'refs/tags/'
refs = [r for r in refs if r.startswith(prefix)]
tags = [repo.lookup_reference(r) for r in refs]
tags.sort(key=lambda t: t.get_object().commit_time)
def find_first_commit(tag, tags):
tag_commits = [t.get_object().id for t in tags]
last = tag.get_object()
walker = repo.walk(tag.target, pygit2.GIT_SORT_TOPOLOGICAL)
walker.next()
for commit in walker:
if commit.id in tag_commits:
return last
if not commit.message.startswith('Merge '):
last = commit
return last
deltas = []
# Throw out the first one... since we rely on looking backwards to the
# preceding tag.. the first tag will never have that and will skew the average.
for tag in tags[1:]:
date_released = arrow.get(tag.get_object().commit_time)
first_commit = find_first_commit(tag, tags)
date_committed = arrow.get(first_commit.commit_time)
delta = date_released - date_committed
deltas.append(delta.total_seconds())
if verbose:
print "%i, %s, %i, %s" % (
tag.get_object().commit_time,
tag.name,
delta.total_seconds(),
delta)
#print "# max", max(deltas)
#print "# min", min(deltas)
if not deltas:
print "%012d" % 0, project, 'no tagged releases found...'
else:
average = sum(deltas) / len(deltas)
print "%012d" % average, project, "%s" % datetime.timedelta(seconds=average)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment