#!/usr/bin/perl -w # (C) 2004-12-10 Thomas Radke # Some changes by Erik Schnetter # GPL licenced use strict; ### some constants # list of email addresses to send notifications to my $email_list_standard = 'carpet-darcs@lists.carpetcode.org'; my $email_list_experimental = 'carpet-experimental-darcs@lists.carpetcode.org'; # where to find the real darcs executable my $darcs = '/home/darcs/bin/darcs1'; # patch database my %submitters = (); my %timestamps = (); my %comments = (); # sanity check die "Couldn't find executable '$darcs'!\n\n" if (! -x $darcs); open (LOG, ">> /home/darcs/LOG"); print LOG "\n"; print LOG "darcs called:\n"; print LOG "date: ", `date`, "\n"; print LOG "arguments: ", join (' ', @ARGV), "\n"; # short cut for darcs commands other than 'apply --all' my $repodir = ''; exec ($darcs, @ARGV) if (! ($#ARGV == 1 && ($ARGV[0] eq 'apply' && $ARGV[1] eq '--all')) && ! ($#ARGV == 3 && ($ARGV[0] eq 'apply' && $ARGV[1] eq '--all' && $ARGV[2] eq '--repodir' && ($repodir = $ARGV[3])))); print LOG "calling darcs:\n"; # open a pipe for running darcs on the other end open (DARCS, "| $darcs @ARGV") || die "Couldn't open pipe to darcs !\n"; # skip everything before the 'New patches:' section while () { print DARCS; print LOG; last if (/^New patches:$/); } # separator for a patch's header and its contents my $endmarker = '] {'; # now parse individual patches while () { print DARCS; print LOG; # each patch starts with a line '[' next if (! /^\[(.+)$/); my $patch = $1; # on the next line follow the submitter's email address # and the timestamp of the patch $_ = ; print DARCS; print LOG; next if (! /^(.+)\*\*(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})($endmarker)??$/o); # add this patch to the database $submitters{$patch} = $1; # convert the timestamp into some readable form 'YYYY-MM-DD HH:MM:SS' $timestamps{$patch} = "$2-$3-$4 $5:$6:$7"; # everything until an end-marker string belongs to # a long comment for this patch if (! $8) { while () { print DARCS; print LOG; last if (/^$endmarker$/); $comments{$patch} .= $_; } delete $submitters{$patch} if (! ($_ && /^$endmarker$/)); } # skip everything that makes out the patch's contents # (i.e., read away until a single line '}' matches) while () { print DARCS; print LOG; last if (/^}$/); } } close (DARCS) || die "Failed to run darcs command '$darcs @ARGV'\n"; print LOG "(that was the patch set)\n"; print LOG "submitters: ", join (' ', %submitters), "\n"; print LOG "done.\n"; if ($repodir eq '') { $repodir = `pwd`; chomp $repodir; } $repodir =~ s+^.*/home/+~+; my $email_list = $email_list_standard; if ($repodir eq '~darcs/carpet-experimental') { $email_list = $email_list_experimental; } # now send out notification email(s) foreach my $patch (keys %submitters) { # Not safe, because the shell expands meta-characters: #open (NOTIFY, "| mail -s '$patch' $email_list"); # More elegant, but only in Perl 5.8 and later: #open (NOTIFY, '|-', 'mail', '-s', $patch, $email_list); # Safe, I think: open (NOTIFY, '|-') || exec 'mail', '-s', $patch, $email_list; #print NOTIFY "A new patch has been pushed into the Carpet repository:\n\n"; print NOTIFY "The Carpet repository at $repodir received a new patch:\n\n"; print NOTIFY " $patch\n\n"; print NOTIFY "This patch was recorded by " . "${submitters{$patch}} at ${timestamps{$patch}}."; if ($comments{$patch}) { print NOTIFY "\n\nThe long comment for this patch reads:\n\n"; print NOTIFY $comments{$patch}; } close (NOTIFY); }