Code cleanup
[crawl.git] / crawl-ref / git-hooks / crawl-ref-cia
blobd322ba4c47c6b582afc39e798f769ede0f101bad
1 #!/usr/bin/perl -w
3 # ciabot -- Mail a git log message to a given address, for the purposes of CIA
5 # Loosely based on cvslog by Russ Allbery <rra@stanford.edu>
6 # Copyright 1998 Board of Trustees, Leland Stanford Jr. University
8 # Copyright 2001, 2003, 2004, 2005 Petr Baudis <pasky@ucw.cz>
10 # This program is free software; you can redistribute it and/or modify it under
11 # the terms of the GNU General Public License version 2, as published by the
12 # Free Software Foundation.
14 # The master location of this file is in the Cogito repository
15 # (see http://www.kernel.org/git/).
17 # This program is designed to run as the .git/hooks/post-commit hook. It takes
18 # the commit information, massages it and mails it to the address given below.
20 # The calling convention of the post-commit hook is:
22 # .git/hooks/post-commit $commit_sha1 $branch_name
24 # If it does not work, try to disable $xml_rpc in the configuration section
25 # below. Also, remember to make the hook file executable.
28 # Note that you can (and it might be actually more desirable) also use this
29 # script as the GIT update hook:
31 # refname=${1#refs/heads/}
32 # [ "$refname" = "master" ] && refname=
33 # oldhead=$2
34 # newhead=$3
35 # for merged in $(git-rev-list $newhead ^$oldhead | tac); do
36 # /path/to/ciabot.pl $merged $refname
37 # done
39 # This is useful when you use a remote repository that you only push to. The
40 # update hook will be triggered each time you push into that repository, and
41 # the pushed commits will be reported through CIA.
43 use strict;
44 use vars qw ($project $from_email $dest_email $noisy $rpc_uri $sendmail
45 $xml_rpc $ignore_regexp $alt_local_message_target);
50 ### Configuration
52 # Project name (as known to CIA).
53 $project = 'crawl-ref';
55 # The from address in generated mails.
56 $from_email = 'dshaligram@users.sourceforge.net';
58 # Mail all reports to this address.
59 $dest_email = 'cia@cia.vc';
61 # If using XML-RPC, connect to this URI.
62 $rpc_uri = 'http://cia.vc/RPC2';
64 # Path to your USCD sendmail compatible binary (your mailer daemon created this
65 # program somewhere).
66 $sendmail = '/usr/sbin/sendmail';
68 # If set, the script will send CIA the full commit message. If unset, only the
69 # first line of the commit message will be sent.
70 $noisy = 0;
72 # This script can communicate with CIA either by mail or by an XML-RPC
73 # interface. The XML-RPC interface is faster and more efficient, however you
74 # need to have RPC::XML perl module installed, and some large CVS hosting sites
75 # (like Savannah or Sourceforge) might not allow outgoing HTTP connections
76 # while they allow outgoing mail. Also, this script will hang and eventually
77 # not deliver the event at all if CIA server happens to be down, which is
78 # unfortunately not an uncommon condition.
79 $xml_rpc = 0;
81 # This variable should contain a regexp, against which each file will be
82 # checked, and if the regexp is matched, the file is ignored. This can be
83 # useful if you do not want auto-updated files, such as e.g. ChangeLog, to
84 # appear via CIA.
86 # The following example will make the script ignore all changes in two specific
87 # files in two different modules, and everything concerning module 'admin':
89 # $ignore_regexp = "^(gentoo/Manifest|elinks/src/bfu/inphist.c|admin/)";
90 $ignore_regexp = "";
92 # It can be useful to also grab the generated XML message by some other
93 # programs and e.g. autogenerate some content based on it. Here you can specify
94 # a file to which it will be appended.
95 $alt_local_message_target = "";
100 ### The code itself
102 use vars qw ($commit $tree @parent $author $committer);
103 use vars qw ($user $branch $rev @files $logmsg $message);
104 my $line;
108 ### Input data loading
111 # The commit stuff
112 $commit = $ARGV[0];
113 $branch = $ARGV[1];
115 open COMMIT, "git-cat-file commit $commit|" or die "git-cat-file commit $commit: $!";
116 my $state = 0;
117 $logmsg = '';
118 while (defined ($line = <COMMIT>)) {
119 if ($state == 1) {
120 $logmsg .= $line;
121 $noisy or $state++;
122 next;
123 } elsif ($state > 1) {
124 next;
127 chomp $line;
128 unless ($line) {
129 $state = 1;
130 next;
133 my ($key, $value) = split(/ /, $line, 2);
134 if ($key eq 'tree') {
135 $tree = $value;
136 } elsif ($key eq 'parent') {
137 push(@parent, $value);
138 } elsif ($key eq 'author') {
139 $author = $value;
140 } elsif ($key eq 'committer') {
141 $committer = $value;
144 close COMMIT;
146 open DIFF, "git-diff-tree -r $parent[0] $tree|" or die "git-diff-tree $parent[0] $tree: $!";
147 while (defined ($line = <DIFF>)) {
148 chomp $line;
149 my @f;
150 (undef, @f) = split(/\t/, $line, 2);
151 push (@files, @f);
153 close DIFF;
156 # Figure out who is doing the update.
157 # XXX: Too trivial this way?
158 ($user) = $author =~ /<(.*?)@/;
160 # HACK to convert CIA's idea of committeers names to match the IRC handles
161 # Developers:
162 $user =~ s/stefanor/sorear/;
163 $user =~ s/evktalo/Keskitalo/;
164 $user =~ s/dploog/dpeg/;
165 $user =~ s/bookofjude/due/;
166 $user =~ s/zelgadis/Matthew_Cline/;
167 $user =~ s/dshaligram/greensnark/;
168 $user =~ s/rvollmert/by/;
169 $user =~ s/ottochar/pointless_/;
170 $user =~ s/enne\.?walker/Enne/;
171 $user =~ s/steven/neunon/;
172 $user =~ s/scintilla/greensnark/;
173 $user =~ s/burnhamrobertp/Cryp71c/;
174 $user =~ s/^muu+$/Mu/i;
175 $user =~ s/raphael.langella/galehar/;
177 # Other regular contributorss
178 $user =~ s/chriscampbell89/MarvinPA/;
179 $user =~ s/homelesspete/Twinge/;
180 $user =~ s/yobbobandana/yobbo/;
181 $user =~ s/thevalrus/valrus/;
183 $rev = substr($commit, 0, 12);
188 ### Remove to-be-ignored files
190 @files = grep { $_ !~ m/$ignore_regexp/; } @files
191 if ($ignore_regexp);
192 exit unless @files;
196 ### Compose the mail message
199 my ($VERSION) = '1.0';
200 my $ts = time;
202 $message = <<EM
203 <message>
204 <generator>
205 <name>CIA Perl client for Git</name>
206 <version>$VERSION</version>
207 </generator>
208 <source>
209 <project>$project</project>
212 $message .= " <branch>$branch</branch>" if ($branch);
213 $message .= <<EM
214 </source>
215 <timestamp>
217 </timestamp>
218 <body>
219 <commit>
220 <author>$user</author>
221 <revision>$rev</revision>
222 <files>
226 foreach (@files) {
227 s/&/&amp;/g;
228 s/</&lt;/g;
229 s/>/&gt;/g;
230 $message .= " <file>$_</file>\n";
233 $logmsg =~ s/&/&amp;/g;
234 $logmsg =~ s/</&lt;/g;
235 $logmsg =~ s/>/&gt;/g;
237 $message .= <<EM
238 </files>
239 <log>
240 $logmsg
241 </log>
242 </commit>
243 </body>
244 </message>
250 ### Write the message to an alt-target
252 if ($alt_local_message_target and open (ALT, ">>$alt_local_message_target")) {
253 print ALT $message;
254 close ALT;
259 ### Send out the XML-RPC message
262 if ($xml_rpc) {
263 # We gotta be careful from now on. We silence all the warnings because
264 # RPC::XML code is crappy and works with undefs etc.
265 $^W = 0;
266 $RPC::XML::ERROR if (0); # silence perl's compile-time warning
268 require RPC::XML;
269 require RPC::XML::Client;
271 my $rpc_client = new RPC::XML::Client $rpc_uri;
272 my $rpc_request = RPC::XML::request->new('hub.deliver', $message);
273 my $rpc_response = $rpc_client->send_request($rpc_request);
275 unless (ref $rpc_response) {
276 die "XML-RPC Error: $RPC::XML::ERROR\n";
278 exit;
283 ### Send out the mail
286 # Open our mail program
288 open (MAIL, "| $sendmail -t -oi -oem") or die "Cannot execute $sendmail : " . ($?>>8);
291 # The mail header
293 print MAIL <<EOM;
294 From: $from_email
295 To: $dest_email
296 Content-type: text/xml
297 Subject: DeliverXML
301 print MAIL $message;
304 # Close the mail
306 close MAIL;
307 die "$0: sendmail exit status " . ($? >> 8) . "\n" unless ($? == 0);
309 # vi: set sw=2: