From f69dcdb5e2fe181f6ede50ae4840e3892891f210 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 21 Apr 2010 14:32:16 -0400 Subject: Incorporate latest version of CIA hook. --- repo/hooks/ciabot.py | 158 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 61 deletions(-) (limited to 'repo') diff --git a/repo/hooks/ciabot.py b/repo/hooks/ciabot.py index 57e80d41..a1d20251 100755 --- a/repo/hooks/ciabot.py +++ b/repo/hooks/ciabot.py @@ -2,38 +2,48 @@ # Copyright (c) 2010 Eric S. Raymond # Distributed under BSD terms. # -# Thiu is version 1.1 of ciabot.py -# # 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 in a post-commit hook or in an update -# hook. +# usage: ciabot.py [-V] [-n] [-p projectname] [refname [commits...]] # -# In post-commit, run it without arguments. It will query for current HEAD and -# the latest commit ID to get the information it needs. +# This script is meant to be run either in a post-commit hook or in an +# update hook. If there's nothing unusual about your hosting setup, +# you can specify the project name with a -p option and avoid having +# to modify this script. Try it with -n to see the notification mail +# dumped to stdout and verify that it looks sane. With -V it dumps its +# version and exits. # -# In update, call it with a refname followed by a list of commits. +# In post-commit, run it without arguments (other than possibly a -p +# option). It will query for current HEAD and the latest commit ID to +# get the information it needs. # -# ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac) +# In update, call it with a refname followed by a list of commits: +# You want to reverse the order git rev-list emits becxause it lists +# from most recent to oldest. # -# Note: this script uses mail, not XML-RPC, in order to avoid stalling -# until timeout when the CIA XML-RPC server is down. +# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac) # -# Call with -n to see the notification mail dumped to stdout rather -# than shipped to CIA. This may be useful for debugging purposes. +# Configuration variables affecting this script: +# ciabot.project = name of the project (makes -p option unnecessary) +# ciabot.xmlrpc = if true, ship notifications via XML-RPC +# ciabot.revformat = format in which the revision is shown # - +# The revformat variable may have the following values +# raw -> full hex ID of commit +# short -> first 12 chars of hex ID +# describe = -> desescription relative to last tag, falling back to short +# The default is 'describe'. # -# The project as known to CIA. You will want to change this: +# Note: the shell ancestors of this script used mail, not XML-RPC, in +# order to avoid stalling until timeout when the CIA XML-RPC server is +# down. It is unknown whether this is still an issue in 2010, but we +# default to mail just in case. (Using XML-RPC guarantees that multiple +# notifications shipped from a commit hook will arrive in order.) # -project="GPSD" -# -# You may not need to change these: -# import os, sys, commands, socket, urllib # Name of the repository. @@ -67,7 +77,7 @@ xml = '''\ CIA Python client for Git - %(gitver)s + %(version)s %(generator)s @@ -96,17 +106,20 @@ xml = '''\ # 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" +toaddr = "cia@cia.navi.cx" # Identify the generator script. # Should only change when the script itself gets a new home and maintainer. -generator="http://www.catb.org/~esr/ciabot.py" +generator = "http://www.catb.org/~esr/ciabot.py" +version = "3.3" def do(command): return commands.getstatusoutput(command)[1] +revformat = do("git config --get ciabot.revformat") + def report(refname, merged): - "Generare a commit notification to be reported to CIA" + "Generate a commit notification to be reported to CIA" # Try to tinyfy a reference to a web view for this commit. try: @@ -116,26 +129,25 @@ def report(refname, merged): branch = os.path.basename(refname) - # Compute a shortnane for the revision - rev = do("git describe ${merged} 2>/dev/null") or merged[:12] + # Compute a description for the revision + if revformat == 'raw': + rev = merged + elif revformat == 'short': + rev = '' + else: # rev == 'describe' + rev = do("git describe %s 2>/dev/null" % merged) + if not rev: + rev = merged[:12] # Extract the neta-information for the commit - rawcommit = do("git cat-file commit " + merged) files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-&-'") - inheader = True - headers = {} - logmsg = "" - for line in rawcommit.split("\n"): - if inheader: - if line: - fields = line.split() - headers[fields[0]] = " ".join(fields[1:]) - else: - inheader = False - else: - logmsg = line - break - (author, ts) = headers["author"].split(">") + metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%at%n%s' " + merged) + (author, ts, logmsg) = metainfo.split("\n") + + # This discards the part of the authors addrsss after @. + # Might be be nice to ship the full email address, if not + # for spammers' address harvesters - getting this wrong + # would make the freenode #commits channel into harvester heaven. author = author.replace("<", "").split("@")[0].split()[-1] # This ignores the timezone. Not clear what to do with it... @@ -158,41 +170,65 @@ Subject: DeliverXML return message if __name__ == "__main__": - # We''ll need the git version number. - gitver = do("git --version").split()[0] + import getopt - # Add the git private command directory to the command path. - os.environ["PATH"] += ":" + do("git --exec-path") + try: + (options, arguments) = getopt.getopt(sys.argv[1:], "np:V") + except getopt.GetoptError, msg: + print "ciabot.py: " + str(msg) + raise SystemExit, 1 + + notify = True + project = None + for (switch, val) in options: + if switch == '-p': + project = val + elif switch == '-n': + notify = False + elif switch == '-V': + print "ciabot.py: version", version + sys.exit(0) + + if not project: + project = do("git config --get ciabot.project") + + # Cough and die if user has not specified a project + if not project: + sys.stderr.write("ciabot.py: no project specified, bailing out.\n") + sys.exit(1) urlprefix = urlprefix % globals() - # Call this script with -n to dump the notification mail to stdout - mailit = True - if len(sys.argv) > 1 and sys.argv[1] == '-n': - mailit = False - sys.argv.pop(1) - # The script wants a reference to head followed by the list of # commit ID to report about. - if len(sys.argv) == 1: + if len(arguments) == 0: refname = do("git symbolic-ref HEAD 2>/dev/null") merges = [do("git rev-parse HEAD")] else: - refname = sys.argv[1] - merges = sys.argv[2:] - - if mailit: - import smtplib - server = smtplib.SMTP('localhost') + refname = arguments[0] + merges = arguments[1:] + + if notify: + xmlrpc = do("git config --get xmlrpc") + xmlrpc = xmlrpc and xmlrpc != "false" + if xmlrpc: + import xmlrpclib + server = xmlrpclib.Server('http://cia.navi.cx/RPC2'); + else: + import smtplib + server = smtplib.SMTP('localhost') for merged in merges: message = report(refname, merged) - if mailit: - server.sendmail(fromaddr, [toaddr], message) - else: + if not notify: print message + elif xmlrpc: + server.hub.deliver(message) + else: + server.sendmail(fromaddr, [toaddr], message) - if mailit: - server.quit() + if notify: + if not xmlrpc: + server.quit() #End -- cgit v1.2.1