Skip to content

Commit fab4b04

Browse files
committed
Merge branch 'maint-1.7.11' into maint
* maint-1.7.11: contrib/ciabot: Get ciabot configuration from git variables
2 parents 889d358 + c142616 commit fab4b04

File tree

2 files changed

+156
-118
lines changed

2 files changed

+156
-118
lines changed

contrib/ciabot/ciabot.py

Lines changed: 89 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,41 @@
1111
#
1212
# This script is meant to be run either in a post-commit hook or in an
1313
# update hook. If there's nothing unusual about your hosting setup,
14-
# you can specify the project name with a -p option and avoid having
15-
# to modify this script. Try it with -n to see the notification mail
16-
# dumped to stdout and verify that it looks sane. With -V it dumps its
17-
# version and exits.
14+
# you can specify the project name and repo with config variables and
15+
# avoid having to modify this script. Try it with -n to see the
16+
# notification mail dumped to stdout and verify that it looks
17+
# sane. With -V it dumps its version and exits.
1818
#
19-
# In post-commit, run it without arguments (other than possibly a -p
20-
# option). It will query for current HEAD and the latest commit ID to
21-
# get the information it needs.
19+
# In post-commit, run it without arguments. It will query for
20+
# current HEAD and the latest commit ID to get the information it
21+
# needs.
2222
#
2323
# In update, call it with a refname followed by a list of commits:
24-
# You want to reverse the order git rev-list emits becxause it lists
24+
# You want to reverse the order git rev-list emits because it lists
2525
# from most recent to oldest.
2626
#
2727
# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
2828
#
29-
# Note: this script uses mail, not XML-RPC, in order to avoid stalling
30-
# until timeout when the CIA XML-RPC server is down.
29+
# Configuration variables affecting this script:
30+
# ciabot.project = name of the project (required)
31+
# ciabot.repo = name of the project repo for gitweb/cgit purposes
32+
# ciabot.xmlrpc = if true (default), ship notifications via XML-RPC
33+
# ciabot.revformat = format in which the revision is shown
3134
#
32-
33-
#
34-
# The project as known to CIA. You will either want to change this
35-
# or invoke the script with a -p option to set it.
35+
# The ciabot.repo value defaults to ciabot.project lowercased.
3636
#
37-
project=None
38-
37+
# The revformat variable may have the following values
38+
# raw -> full hex ID of commit
39+
# short -> first 12 chars of hex ID
40+
# describe = -> describe relative to last tag, falling back to short
41+
# The default is 'describe'.
3942
#
40-
# You may not need to change these:
43+
# Note: the CIA project now says only XML-RPC is reliable, so
44+
# we default to that.
4145
#
42-
import os, sys, commands, socket, urllib
43-
44-
# Name of the repository.
45-
# You can hardwire this to make the script faster.
46-
repo = os.path.basename(os.getcwd())
4746

48-
# Fully-qualified domain name of this host.
49-
# You can hardwire this to make the script faster.
50-
host = socket.getfqdn()
47+
import os, sys, commands, socket, urllib
48+
from xml.sax.saxutils import escape
5149

5250
# Changeset URL prefix for your repo: when the commit ID is appended
5351
# to this, it should point at a CGI that will display the commit
@@ -72,7 +70,7 @@
7270
<message>
7371
<generator>
7472
<name>CIA Python client for Git</name>
75-
<version>%(gitver)s</version>
73+
<version>%(version)s</version>
7674
<url>%(generator)s</url>
7775
</generator>
7876
<source>
@@ -98,19 +96,18 @@
9896
# No user-serviceable parts below this line:
9997
#
10098

101-
# Addresses for the e-mail. The from address is a dummy, since CIA
102-
# will never reply to this mail.
103-
fromaddr = "CIABOT-NOREPLY@" + host
104-
99+
# Where to ship e-mail notifications.
100+
105101

106102
# Identify the generator script.
107103
# Should only change when the script itself gets a new home and maintainer.
108-
generator="http://www.catb.org/~esr/ciabot.py"
104+
generator = "http://www.catb.org/~esr/ciabot.py"
105+
version = "3.5"
109106

110107
def do(command):
111108
return commands.getstatusoutput(command)[1]
112109

113-
def report(refname, merged):
110+
def report(refname, merged, xmlrpc=True):
114111
"Generate a commit notification to be reported to CIA"
115112

116113
# Try to tinyfy a reference to a web view for this commit.
@@ -121,32 +118,27 @@ def report(refname, merged):
121118

122119
branch = os.path.basename(refname)
123120

124-
# Compute a shortnane for the revision
125-
rev = do("git describe '"+ merged +"' 2>/dev/null") or merged[:12]
126-
127-
# Extract the neta-information for the commit
128-
rawcommit = do("git cat-file commit " + merged)
121+
# Compute a description for the revision
122+
if revformat == 'raw':
123+
rev = merged
124+
elif revformat == 'short':
125+
rev = ''
126+
else: # revformat == 'describe'
127+
rev = do("git describe %s 2>/dev/null" % merged)
128+
if not rev:
129+
rev = merged[:12]
130+
131+
# Extract the meta-information for the commit
129132
files=do("git diff-tree -r --name-only '"+ merged +"' | sed -e '1d' -e 's-.*-<file>&</file>-'")
130-
inheader = True
131-
headers = {}
132-
logmsg = ""
133-
for line in rawcommit.split("\n"):
134-
if inheader:
135-
if line:
136-
fields = line.split()
137-
headers[fields[0]] = " ".join(fields[1:])
138-
else:
139-
inheader = False
140-
else:
141-
logmsg = line
142-
break
143-
(author, ts) = headers["author"].split(">")
133+
metainfo = do("git log -1 '--pretty=format:%an <%ae>%n%at%n%s' " + merged)
134+
(author, ts, logmsg) = metainfo.split("\n")
135+
logmsg = escape(logmsg)
144136

145-
# This discards the part of the authors addrsss after @.
146-
# Might be bnicece to ship the full email address, if not
137+
# This discards the part of the author's address after @.
138+
# Might be be nice to ship the full email address, if not
147139
# for spammers' address harvesters - getting this wrong
148140
# would make the freenode #commits channel into harvester heaven.
149-
author = author.replace("<", "").split("@")[0].split()[-1]
141+
author = escape(author.replace("<", "").split("@")[0].split()[-1])
150142

151143
# This ignores the timezone. Not clear what to do with it...
152144
ts = ts.strip().split()[0]
@@ -155,8 +147,7 @@ def report(refname, merged):
155147
context.update(globals())
156148

157149
out = xml % context
158-
159-
message = '''\
150+
mail = '''\
160151
Message-ID: <%(merged)s.%(author)s@%(project)s>
161152
From: %(fromaddr)s
162153
To: %(toaddr)s
@@ -165,34 +156,49 @@ def report(refname, merged):
165156
166157
%(out)s''' % locals()
167158

168-
return message
159+
if xmlrpc:
160+
return out
161+
else:
162+
return mail
169163

170164
if __name__ == "__main__":
171165
import getopt
172166

167+
# Get all config variables
168+
revformat = do("git config --get ciabot.revformat")
169+
project = do("git config --get ciabot.project")
170+
repo = do("git config --get ciabot.repo")
171+
xmlrpc = do("git config --get ciabot.xmlrpc")
172+
xmlrpc = not (xmlrpc and xmlrpc == "false")
173+
174+
host = socket.getfqdn()
175+
fromaddr = "CIABOT-NOREPLY@" + host
176+
173177
try:
174-
(options, arguments) = getopt.getopt(sys.argv[1:], "np:V")
178+
(options, arguments) = getopt.getopt(sys.argv[1:], "np:xV")
175179
except getopt.GetoptError, msg:
176180
print "ciabot.py: " + str(msg)
177181
raise SystemExit, 1
178182

179-
mailit = True
183+
notify = True
180184
for (switch, val) in options:
181185
if switch == '-p':
182186
project = val
183187
elif switch == '-n':
184-
mailit = False
188+
notify = False
189+
elif switch == '-x':
190+
xmlrpc = True
185191
elif switch == '-V':
186-
print "ciabot.py: version 3.2"
192+
print "ciabot.py: version", version
187193
sys.exit(0)
188194

189195
# Cough and die if user has not specified a project
190196
if not project:
191197
sys.stderr.write("ciabot.py: no project specified, bailing out.\n")
192198
sys.exit(1)
193199

194-
# We'll need the git version number.
195-
gitver = do("git --version").split()[0]
200+
if not repo:
201+
repo = project.lower()
196202

197203
urlprefix = urlprefix % globals()
198204

@@ -205,18 +211,29 @@ def report(refname, merged):
205211
refname = arguments[0]
206212
merges = arguments[1:]
207213

208-
if mailit:
209-
import smtplib
210-
server = smtplib.SMTP('localhost')
214+
if notify:
215+
if xmlrpc:
216+
import xmlrpclib
217+
server = xmlrpclib.Server('http://cia.vc/RPC2');
218+
else:
219+
import smtplib
220+
server = smtplib.SMTP('localhost')
211221

212222
for merged in merges:
213-
message = report(refname, merged)
214-
if mailit:
215-
server.sendmail(fromaddr, [toaddr], message)
216-
else:
223+
message = report(refname, merged, xmlrpc)
224+
if not notify:
217225
print message
226+
elif xmlrpc:
227+
try:
228+
# RPC server is flaky, this can fail due to timeout.
229+
server.hub.deliver(message)
230+
except socket.error, e:
231+
sys.stderr.write("%s\n" % e)
232+
else:
233+
server.sendmail(fromaddr, [toaddr], message)
218234

219-
if mailit:
220-
server.quit()
235+
if notify:
236+
if not xmlrpc:
237+
server.quit()
221238

222239
#End

0 commit comments

Comments
 (0)