[llvm-commits] CVS: CVSROOT/commit-diffs.pl
John Criswell
criswell at cs.uiuc.edu
Fri Nov 3 08:44:03 PST 2006
Changes in directory CVSROOT:
commit-diffs.pl added (r1.1)
---
Log message:
Commit diffs script for InternalCVS repository. Simply is able to send
email to multiple people.
---
Diffs of the changes: (+240 -0)
commit-diffs.pl | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 240 insertions(+)
Index: CVSROOT/commit-diffs.pl
diff -c /dev/null CVSROOT/commit-diffs.pl:1.1
*** /dev/null Fri Nov 3 10:44:03 2006
--- CVSROOT/commit-diffs.pl Fri Nov 3 10:43:53 2006
***************
*** 0 ****
--- 1,240 ----
+ #! /usr/bin/perl
+
+ use POSIX qw(uname);
+
+ # We have to spawn another process to avoid CVS locking.
+ if (fork()) {
+ exit(0);
+ }
+
+ $DEFAULT_ADMIN = 'llvm-commits\@cs.uiuc.edu';
+ $DEBUG = 0;
+ %REALNAMESTABLE = (
+ 'reid' => 'Reid Spencer <reid at x10sys.com>',
+ 'sampo' => 'Nate Begeman <natebegeman at mac.com>',
+ 'jeffc' => 'Jeff Cohen <jeffc at jolt-lang.org>',
+ 'duraid' => 'Duraid Madina <duraid at octopus.com.au>',
+ 'jlaskey' => 'Jim Laskey <jlaskey at apple.com>',
+ 'evancheng' => 'Evan Cheng <evan.cheng at apple.com>',
+ 'resistor' => 'Owen Anderson <resistor at mac.com>',
+ 'rafael' => 'Rafael Espindola <rafael.espindola at gmail.com>',
+ 'ghost' => 'Vladimir Prus <ghost at cs.msu.su>',
+ 'dpatel' => 'Devang Patel <dpatel at apple.com>',
+ 'patjenk' => 'Patrick Jenkins <pjenkins at apple.com>',
+ 'asl' => 'Anton Korobeynikov <asl at math.spbu.ru>',
+ 'void' => 'Bill Wendling <isanbard at gmail.com>',
+ 'nicholas' => 'Nick Lewycky <nicholas at mxc.ca>',
+ 'lattner' => 'Chris Lattner <sabre at nondot.org>',
+ 'tbrethou' => 'Tanya Lattner <tonic at nondot.org>',
+ 'sheng' => 'Zhou Sheng <zhousheng00 at gmail.com>'
+ );
+
+ # A trivial script example to send mail on every CVS commit.
+ # The mail sent includes change summary, log message and a unidiff
+ # about the changes.
+
+ # Original author: Jouni Heikniemi <jouni at heikniemi.net>
+ # This script was improved by Misha & Chris:
+ # * Hacked to work under Unix
+ # * Displays contents of new files (`cvs diff -r0 -r1.1')
+ # * Displays branch name in the subject line
+ # Brian Gaeke added support for people who commit via 'pserver'
+ # using the separate CVSROOT/passwd file.
+
+ ######################################################################
+ # CVS loginfo format specifier '%{sVv}' produces items like
+ # 'source.c,1.2,1.3', 'source2.c,NONE,1.1' and 'source3.c,1.5,NONE'
+ # for change, add and remove, respectively. This method parses
+ # those to a hash and returns a ref to it.
+
+ sub createChangeItem($) { #($)
+ my @arr = split(',', shift);
+ my %change;
+ $change{'filename'} = $arr[0];
+ $change{'oldrev'} = $arr[1];
+ $change{'newrev'} = $arr[2];
+ if ($arr[1] eq 'NONE') {
+ $change{'type'} = 'add';
+ } elsif ($arr[2] eq 'NONE') {
+ $change{'type'} = 'rm';
+ } else {
+ $change{'type'} = 'c';
+ }
+ return \%change;
+ }
+
+ ## Main code:
+
+ # Do a small delay so that the main CVS task finishes and
+ # releases locks first.
+
+ sleep 10;
+
+ if ($DEBUG) {
+ for (my $i = 0; $i <= $#ARGV; ++$i) {
+ print "ARGV[$i] = '$ARGV[$i]'\n";
+ }
+ }
+
+ # Find out who we shall send mail to
+ my $target = $ARGV[1] || $DEFAULT_ADMIN;
+
+ # Manipulate the CVS's change info; see docs for further information.
+ my @changes = split(' ', $ARGV[0]);
+ my $changedir = shift @changes;
+
+ if ($DEBUG) {
+ print join("\n--\n", @changes);
+ print "num changes: " .scalar(@changes) . "\n";
+ }
+
+ if ($changes[0] ne "-") { # Ignore " - New directory" messages
+ for ($j=0; $j < scalar(@changes); $j++) {
+ $changeItems[$j] = createChangeItem($changes[$j]);
+ }
+ }
+
+ print "changedir: $changedir\n" if $DEBUG;
+
+ my @loginfodata = <STDIN>;
+ #print "loginfo: ". join("\n--\n", @loginfodata) if $DEBUG;
+
+ # Pick up the committer's log message and branch from the loginfo we received
+ my @logmessage;
+ my $islogmessage = 0;
+ my $branch = "";
+
+ foreach $s (@loginfodata) {
+ if ($islogmessage) {
+ $s =~ s|([pP][rR]\s*([0-9]+))|$1: http://llvm.org/PR$2 |g;
+ $s =~ s|([bB][uU][gG]\s*([0-9]+))|$1: http://llvm.org/PR$2 |g;
+ @logmessage = (@logmessage, $s);
+ next;
+ }
+
+ if ($s =~ /^Log Message:/) {
+ $islogmessage = 1;
+ next;
+ } elsif ($s =~ m/^\s+Tag:/) {
+ $branch = $s;
+ chop $branch;
+ $branch =~ s/^\s+Tag:\s(.+)/$1/;
+ }
+ }
+
+ # Format the output
+
+ my $msg = "\n\nChanges in directory $changedir:\n\n";
+
+ sub find_responsible_party {
+ my $newrev = $m->{'newrev'};
+ my $path = "$changedir/$m->{'filename'}";
+ my @histlines =
+ split ("\n", `cvs history -cal -f $path`);
+ my $DateRE = "[-:/0-9 ]+\\+[0-9]+";
+ my $result = "";
+ foreach my $line (@histlines) {
+ my ($Type, $Date, $UID, $Rev, $Filename);
+ if ($line =~ /([AMRUGC]) ($DateRE) ([^ ]+) +([^ ]+) +([^ ]+) +([^ ]+)/) {
+ ($Type, $Date, $UID, $Rev, $Filename) = ($1, $2, $3, $4, "$6/$5");
+ if ($Rev eq $newrev && $Filename == $path) { return $UID; }
+ }
+ }
+ return undef;
+ }
+
+ sub get_from {
+ my ($userid) = @_;
+ if (exists $REALNAMESTABLE{$userid}) { return $REALNAMESTABLE{$userid}; }
+ # try the system passwd database.
+ my ($name,$passwd,$uid,$gid,$quota,$cmnt,$gcos, at rest) = getpwnam ($userid);
+ if ($gcos) { return "\"$gcos\" <$userid>"; }
+ return "$userid"; # couldn't find it.
+ }
+
+ my $diffs = "";
+ my $filePath = "$changedir/";
+
+ foreach $m (@changeItems) {
+ $filePath .= "$m->{'filename'} ";
+ if ($m->{'type'} eq 'add') {
+ $msg .= "$m->{'filename'} added (r$m->{'newrev'})\n";
+ $diffs .= `cvs -Qf rdiff -r0 -r$m->{'newrev'} $changedir/$m->{'filename'} 2> /dev/null` . "\n\n";
+ } elsif ($m->{'type'} eq 'rm') {
+ $msg .= "$m->{'filename'} (r$m->{'oldrev'}) removed\n";
+ } else {
+ $msg .= "$m->{'filename'} updated: $m->{'oldrev'} -> $m->{'newrev'}\n";
+ $diffs .= `cvs -Qf rdiff -u -r $m->{'oldrev'} -r $m->{'newrev'} $changedir/$m->{'filename'} 2> /dev/null` . "\n\n";
+ }
+ unless ($responsible_party) {
+ $responsible_party = get_from (find_responsible_party ());
+ }
+ }
+
+ # Do a simple rough count of the differences.
+ $msg .= "---\nLog message:\n\n" . join('', at logmessage);
+ my $pluses = 0;
+ my $minuses = 0;
+ foreach my $line (split /\n/, $diffs) {
+ if ($line !~ /^\+\+\+ /) {
+ if ($line !~ /^\-\-\- /) {
+ $pluses++ if $line =~ /^\+/;
+ $minuses++ if $line =~ /^\-/;
+ }
+ }
+ }
+ $msg .= "\n---\nDiffs of the changes: (+$pluses -$minuses)\n\n";
+
+
+ # Give diffstat the diff to count.
+ use IPC::Open3;
+ my $DiffStatWrite;
+ my $DiffStatRead;
+ open3($DiffStatWrite, $DiffStatRead, "", "diffstat");
+ print $DiffStatWrite $diffs;
+ close($DiffStatWrite);
+
+ # Read the input back from diffstat.
+ my $Tmp = $/;
+ undef $/; # read all at once.
+ $msg .= <$DiffStatRead>;
+ $msg .= "\n\n";
+ close $DiffStatRead;
+ $/ = $tmp;
+
+
+ # Finally, add on the diffs themselves.
+ $msg .= $diffs;
+
+ # Include the branch, if applicable, into the subject line of the email
+ my $emailSubject = "";
+ if ($branch ne "") {
+ $emailSubject = "[$branch]";
+ }
+ $emailSubject .= " CVS: $filePath";
+
+ # The world cries out for a standard-issue version of Mail::Send.
+ sub send_msg {
+ my ($from, $to, $subject, $msg) = @_;
+ foreach my $prog ("/usr/lib/sendmail", "/usr/sbin/sendmail",
+ "/usr/libexec/sendmail") {
+ if (-x $prog) { $MAILERPROG = $prog; last; }
+ }
+ die "Can't find sendmail" unless $MAILERPROG && -x $MAILERPROG;
+ open (MAILER, "|$MAILERPROG -oi -oem -t")
+ or die "Can't run sendmail";
+ print MAILER <<END;
+ From: $from
+ To: $to
+ Subject: $subject
+
+ $msg
+ END
+ close MAILER or die "Failed running sendmail";
+ }
+
+ # Send it.
+ for (my $i = 1; $i <= $#ARGV; ++$i) {
+ send_msg ($responsible_party, $ARGV[$i], $emailSubject, $msg);
+ }
+ exit 0;
More information about the llvm-commits
mailing list