From c7d503f5eb7105644a901f80606c52f6fa9c0b77 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 27 Mar 2010 06:12:38 -0400 Subject: First cut at Python version of CIA hook. --- repo/hooks/ciabot.py | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100755 repo/hooks/ciabot.py (limited to 'repo') diff --git a/repo/hooks/ciabot.py b/repo/hooks/ciabot.py new file mode 100755 index 00000000..b788b56a --- /dev/null +++ b/repo/hooks/ciabot.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python +# Distributed under the terms of the GNU General Public License v2 +# Copyright (c) 2010 Eric S. Raymond +# +# This script contains porcelain and porcelain byproducts. +# It's Python because the Python standard libraries avoid portability/security +# issues raised by callouts in the ancestral Perl and sh scripts. It should +# be compatible back to Python 2.1.5. +# +# It is meant to be run either on a post-commit hook or in an update +# hook: +# +# post-commit: It queries for current HEAD and latest commit ID to get the +# information it needs. +# +# update: You have to call it once per merged commit: +# +# refname=$1 +# oldhead=$2 +# newhead=$3 +# for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do +# /path/to/ciabot.py ${refname} ${merged} +# done +# +# Note: this script uses mail, not XML-RPC, in order to avoid stalling +# until timeout when the XML-RPC server is down. +# +# Call with -n to see the notification mail dumped to stdout rather +# than shipped to CIA. +# +import os, sys, commands, socket, urllib +# +# The project as known to CIA. You will want to change this: +# +project="GPSD" + +# +# You may not need to change these: +# + +# Name of the repository. +# You can hardwire this to make the script faster. +repo = os.path.basename(os.getcwd()) + +# Fully-qualified domain name of this host. +# You can hardwire this to make the script faster. +host = socket.getfqdn() + +# Changeset URL prefix for your repo: when the commit ID is appended +# to this, it should point at a CGI that will display the commit +# through gitweb or something similar. The default will probably +# work if you have a typical gitweb/cgit setup. +# +#urlprefix="http://%(host)s/cgi-bin/gitweb.cgi?p=%(repo)s;a=commit;h="%locals() +urlprefix="http://%(host)s/cgi-bin/cgit.cgi/%(repo)s/commit/?id="%locals() + +# +# No user-serviceable parts below this line: +# + +def do(command): + return commands.getstatusoutput(command)[1] + +# Addresses for the e-mail. The from address is a dummy, since CIA +# will never reply to this mail. +fromaddr = "CIABOT-NOREPLY@" + host +toaddr = "cia@cia.vc" + +# Identify the generator script. +# Should only change when the script itself has a new home +generator="http://www.catb.org/~esr/ciabot.sh" + +# Should add to the command path both places sendmail is likely to lurk, +# and the git private command directory. +os.environ["PATH"] += ":/usr/sbin/:" + do("git --exec-path") + +# Call this script with -n tp dump the notification mail to stdout +mailit = True +if sys.argv[1] == '-n': + mailit = False + sys.argv.pop(1) + +# Script wants a reference to head followed by the commit ID to notify about. +if len(sys.argv) == 1: + refname = do("git symbolic-ref HEAD 2>/dev/null") + merged = do("git rev-parse HEAD") +else: + refname = sys.argv[1] + merged = sys.argv[2] + +# This tries to turn your gitwebbish URL into a tinyurl so it will take up +# less space on the IRC notification line. You can tweak the tinyfier +# service if you need to. +tinyifier = "http://tinyurl.com/api-create.php?url=" +try: + url = open(urllib.urlretrieve(tinyifier + urlprefix + merged)[0]).read() +except: + url = urlprefix + merged + +refname = os.path.basename(refname) +gitver = do("git --version").split()[0] # Git version number + +rev = do("git describe ${merged} 2>/dev/null") or merged[:12] +rawcommit = do("git cat-file commit " + merged) +files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-&-'") + +inheader = True +headers = {} +logmessage = "" +for line in rawcommit.split("\n"): + if inheader: + if line: + fields = line.split() + headers[fields[0]] = " ".join(fields[1:]) + else: + inheader = False + else: + logmessage = line + break +(author, ts) = headers["author"].split(">") +author = author.replace("<", "").split("@")[0].split()[-1] +ts = ts.strip() + +out = '''\ + + + CIA Shell client for Git + %(gitver)s + %(generator)s + + + %(project)s + %(repo)s:%(refname)s + + %(ts)s + + + %(author)s + %(rev)s + + %(files)s + + %(logmessage)s %(url)s + %(url)s + + + +''' % locals() + +message = '''\ +Message-ID: <%(merged)s.%(author)s@%(project)s> +From: %(fromaddr)s +To: %(toaddr)s +Content-type: text/xml +Subject: DeliverXML + +%(out)s''' % locals() + +if mailit: + import smtplib + server = smtplib.SMTP('localhost') + server.sendmail(fromaddr, [toaddr], message) + server.quit() +else: + print message + +#End -- cgit v1.2.1