contrib/ciabot: Get ciabot configuration from git variables
These changes remove all need to modify the ciabot scripts for installation. Instead, per-project configuration can be dome via variables in a [ciabot] section of the config file. Also, correct for the new server address. Signed-off-by: Eric S. Raymond <esr@thyrsus.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Eric S. Raymond committed
Aug 22, 2012 at 06:52 UTC
c142616fb2152d7887f9c38ff20e07167d31b0c8
2 files changed
+156
-118
contrib/ciabot/ciabot.py
+89
-72
@@ -11,43 +11,41 @@
11
#
12
# This script is meant to be run either in a post-commit hook or in an
13
# 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.
18
#
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.
22
#
23
# 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
25
# from most recent to oldest.
26
#
27
# /path/to/ciabot.py ${refname} $(git rev-list ${oldhead}..${newhead} | tac)
28
#
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
34
#
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.
36
#
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'.
42
#
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.
45
#
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())
46
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
49
50
# Changeset URL prefix for your repo: when the commit ID is appended
51
# to this, it should point at a CGI that will display the commit
@@ -72,7 +70,7 @@ xml = '''\
70
<message>
71
<generator>
72
<name>CIA Python client for Git</name>
75
- <version>%(gitver)s</version>
73
+ <version>%(version)s</version>
74
<url>%(generator)s</url>
75
</generator>
76
<source>
@@ -98,19 +96,18 @@ xml = '''\
96
# No user-serviceable parts below this line:
97
#
98
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
-toaddr = "cia@cia.navi.cx"
99
+# Where to ship e-mail notifications.
100
+toaddr = "cia@cia.vc"
101
102
# Identify the generator script.
103
# 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"
106
107
def do(command):
108
return commands.getstatusoutput(command)[1]
109
113
-def report(refname, merged):
110
+def report(refname, merged, xmlrpc=True):
111
"Generate a commit notification to be reported to CIA"
112
113
# Try to tinyfy a reference to a web view for this commit.
@@ -121,32 +118,27 @@ def report(refname, merged):
118
119
branch = os.path.basename(refname)
120
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
132
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)
136
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
139
# for spammers' address harvesters - getting this wrong
140
# 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])
142
143
# This ignores the timezone. Not clear what to do with it...
144
ts = ts.strip().split()[0]
@@ -155,8 +147,7 @@ def report(refname, merged):
147
context.update(globals())
148
149
out = xml % context
158
-
159
- message = '''\
150
+ mail = '''\
151
Message-ID: <%(merged)s.%(author)s@%(project)s>
152
From: %(fromaddr)s
153
To: %(toaddr)s
@@ -165,25 +156,40 @@ Subject: DeliverXML
156
157
%(out)s''' % locals()
158
168
- return message
159
+ if xmlrpc:
160
+ return out
161
+ else:
162
+ return mail
163
164
if __name__ == "__main__":
165
import getopt
166
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
+
177
try:
174
- (options, arguments) = getopt.getopt(sys.argv[1:], "np:V")
178
+ (options, arguments) = getopt.getopt(sys.argv[1:], "np:xV")
179
except getopt.GetoptError, msg:
180
print "ciabot.py: " + str(msg)
181
raise SystemExit, 1
182
179
- mailit = True
183
+ notify = True
184
for (switch, val) in options:
185
if switch == '-p':
186
project = val
187
elif switch == '-n':
184
- mailit = False
188
+ notify = False
189
+ elif switch == '-x':
190
+ xmlrpc = True
191
elif switch == '-V':
186
- print "ciabot.py: version 3.2"
192
+ print "ciabot.py: version", version
193
sys.exit(0)
194
195
# Cough and die if user has not specified a project
@@ -191,8 +197,8 @@ if __name__ == "__main__":
197
sys.stderr.write("ciabot.py: no project specified, bailing out.\n")
198
sys.exit(1)
199
194
- # We'll need the git version number.
195
- gitver = do("git --version").split()[0]
200
+ if not repo:
201
+ repo = project.lower()
202
203
urlprefix = urlprefix % globals()
204
@@ -205,18 +211,29 @@ if __name__ == "__main__":
211
refname = arguments[0]
212
merges = arguments[1:]
213
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')
221
222
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:
225
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)
234
219
- if mailit:
220
- server.quit()
235
+ if notify:
236
+ if not xmlrpc:
237
+ server.quit()
238
239
#End
contrib/ciabot/ciabot.sh
+67
-46
@@ -3,6 +3,8 @@
3
# Copyright (c) 2006 Fernando J. Pereda <ferdy@gentoo.org>
4
# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
5
# Copyright (c) 2010 Eric S. Raymond <esr@thyrsus.com>
6
+# Assistance and review by Petr Baudis, author of ciabot.pl,
7
+# is gratefully acknowledged.
8
#
9
# This is a version 3.x of ciabot.sh; use -V to find the exact
10
# version. Versions 1 and 2 were shipped in 2006 and 2008 and are not
@@ -11,6 +13,7 @@
13
# Note: This script should be considered obsolete.
14
# There is a faster, better-documented rewrite in Python: find it as ciabot.py
15
# Use this only if your hosting site forbids Python hooks.
16
+# It requires: git(1), hostname(1), cut(1), sendmail(1), and wget(1).
17
#
18
# Originally based on Git ciabot.pl by Petr Baudis.
19
# This script contains porcelain and porcelain byproducts.
@@ -19,14 +22,14 @@
22
#
23
# This script is meant to be run either in a post-commit hook or in an
24
# update hook. If there's nothing unusual about your hosting setup,
22
-# you can specify the project name with a -p option and avoid having
23
-# to modify this script. Try it with -n first to see the notification
24
-# mail dumped to stdout and verify that it looks sane. Use -V to dump
25
-# the version and exit.
25
+# you can specify the project name and repo with config variables and
26
+# avoid having to modify this script. Try it with -n to see the
27
+# notification mail dumped to stdout and verify that it looks
28
+# sane. With -V it dumps its version and exits.
29
#
27
-# In post-commit, run it without arguments (other than possibly a -p
28
-# option). It will query for current HEAD and the latest commit ID to
29
-# get the information it needs.
30
+# In post-commit, run it without arguments. It will query for
31
+# current HEAD and the latest commit ID to get the information it
32
+# needs.
33
#
34
# In update, you have to call it once per merged commit:
35
#
@@ -34,33 +37,54 @@
37
# oldhead=$2
38
# newhead=$3
39
# for merged in $(git rev-list ${oldhead}..${newhead} | tac) ; do
37
-# /path/to/ciabot.bash ${refname} ${merged}
40
+# /path/to/ciabot.sh ${refname} ${merged}
41
# done
42
#
40
-# The reason for the tac call ids that git rev-list emits commits from
43
+# The reason for the tac call is that git rev-list emits commits from
44
# most recent to least - better to ship notifactions from oldest to newest.
45
#
43
-# Note: this script uses mail, not XML-RPC, in order to avoid stalling
44
-# until timeout when the CIA XML-RPC server is down.
46
+# Configuration variables affecting this script:
47
+# ciabot.project = name of the project (makes -p option unnecessary)
48
+# ciabot.repo = name of the project repo for gitweb/cgit purposes
49
+# ciabot.revformat = format in which the revision is shown
50
#
46
-
47
-#
48
-# The project as known to CIA. You will either want to change this
49
-# or set the project name with a -p option.
51
+# The ciabot.repo defaults to ciabot.project lowercased.
52
#
51
-project=
52
-
53
+# The revformat variable may have the following values
54
+# raw -> full hex ID of commit
55
+# short -> first 12 chars of hex ID
56
+# describe = -> describe relative to last tag, falling back to short
57
+# The default is 'describe'.
58
#
54
-# You may not need to change these:
59
+# Note: the shell ancestors of this script used mail, not XML-RPC, in
60
+# order to avoid stalling until timeout when the CIA XML-RPC server is
61
+# down. It is unknown whether this is still an issue in 2010, but
62
+# XML-RPC would be annoying to do from sh in any case. (XML-RPC does
63
+# have the advantage that it guarantees notification of multiple commits
64
+# shpped from an update in their actual order.)
65
#
66
57
-# Name of the repository.
58
-# You can hardwire this to make the script faster.
59
-repo="`basename ${PWD}`"
67
+# The project as known to CIA. You can also hardwire this or set it with a
68
+# -p option.
69
+project=$(git config --get ciabot.project)
70
+
71
+# Name of the repo for gitweb/cgit purposes
72
+repo=$(git config --get ciabot.repo)
73
+[ -z $repo] && repo=$(echo "${project}" | tr '[A-Z]' '[a-z]')
74
+
75
+# What revision format do we want in the summary?
76
+revformat=$(git config --get ciabot.revformat)
77
61
-# Fully qualified domain name of the repo host.
62
-# You can hardwire this to make the script faster.
63
-host=`hostname --fqdn`
78
+# Fully qualified domain name of the repo host. You can hardwire this
79
+# to make the script faster. The -f option works under Linux and FreeBSD,
80
+# but not OpenBSD and NetBSD. But under OpenBSD and NetBSD,
81
+# hostname without options gives the FQDN.
82
+if hostname -f >/dev/null 2>&1
83
+then
84
+ hostname=`hostname -f`
85
+else
86
+ hostname=`hostname`
87
+fi
88
89
# Changeset URL prefix for your repo: when the commit ID is appended
90
# to this, it should point at a CGI that will display the commit
@@ -73,13 +97,14 @@ urlprefix="http://${host}/cgi-bin/cgit.cgi/${repo}/commit/?id="
97
# You probably will not need to change the following:
98
#
99
76
-# Identify the script. Should change only when the script itself
77
-# gets a new home and maintainer.
100
+# Identify the script. The 'generator' variable should change only
101
+# when the script itself gets a new home and maintainer.
102
generator="http://www.catb.org/~esr/ciabot/ciabot.sh"
103
+version=3.4
104
105
# Addresses for the e-mail
81
-from="CIABOT-NOREPLY@${host}"
82
-to="cia@cia.navi.cx"
106
+from="CIABOT-NOREPLY@${hostname}"
107
+to="cia@cia.vc"
108
109
# SMTP client to use - may need to edit the absolute pathname for your system
110
sendmail="sendmail -t -f ${from}"
@@ -97,7 +122,7 @@ do
122
case $opt in
123
p) project=$2; shift ; shift ;;
124
n) mode=dumpit; shift ;;
100
- V) echo "ciabot.sh: version 3.2"; exit 0; shift ;;
125
+ V) echo "ciabot.sh: version $version"; exit 0; shift ;;
126
esac
127
done
128
@@ -128,33 +153,29 @@ fi
153
154
refname=${refname##refs/heads/}
155
131
-gitver=$(git --version)
132
-gitver=${gitver##* }
156
+case $revformat in
157
+raw) rev=$merged ;;
158
+short) rev='' ;;
159
+*) rev=$(git describe ${merged} 2>/dev/null) ;;
160
+esac
161
+[ -z ${rev} ] && rev=$(echo "$merged" | cut -c 1-12)
162
134
-rev=$(git describe ${merged} 2>/dev/null)
135
-# ${merged:0:12} was the only bashism left in the 2008 version of this
136
-# script, according to checkbashisms. Replace it with ${merged} here
137
-# because it was just a fallback anyway, and it's worth accepting a
138
-# longer fallback for faster execution and removing the bash
139
-# dependency.
140
-[ -z ${rev} ] && rev=${merged}
141
-
142
-# This discards the part of the author's address after @.
163
+# We discard the part of the author's address after @.
164
# Might be nice to ship the full email address, if not
165
# for spammers' address harvesters - getting this wrong
166
# would make the freenode #commits channel into harvester heaven.
146
-rawcommit=$(git cat-file commit ${merged})
147
-author=$(echo "$rawcommit" | sed -n -e '/^author .*<\([^@]*\).*$/s--\1-p')
148
-logmessage=$(echo "$rawcommit" | sed -e '1,/^$/d' | head -n 1)
149
-logmessage=$(echo "$logmessage" | sed 's/\&/&\;/g; s/</<\;/g; s/>/>\;/g')
150
-ts=$(echo "$rawcommit" | sed -n -e '/^author .*> \([0-9]\+\).*$/s--\1-p')
167
+author=$(git log -1 '--pretty=format:%an <%ae>' $merged)
168
+author=$(echo "$author" | sed -n -e '/^.*<\([^@]*\).*$/s--\1-p')
169
+
170
+logmessage=$(git log -1 '--pretty=format:%s' $merged)
171
+ts=$(git log -1 '--pretty=format:%at' $merged)
172
files=$(git diff-tree -r --name-only ${merged} | sed -e '1d' -e 's-.*-<file>&</file>-')
173
174
out="
175
<message>
176
<generator>
177
<name>CIA Shell client for Git</name>
157
- <version>${gitver}</version>
178
+ <version>${version}</version>
179
<url>${generator}</url>
180
</generator>
181
<source>