- new version.

This commit is contained in:
serek 2004-07-26 14:09:19 +00:00
parent b086a85837
commit 790c7ad648
1 changed files with 184 additions and 73 deletions

View File

@ -5,7 +5,7 @@
# Loosely based on cvslog by Russ Allbery <rra@stanford.edu>
# Copyright 1998 Board of Trustees, Leland Stanford Jr. University
#
# Copyright 2001, 2003 Petr Baudis <pasky@ucw.cz>
# Copyright 2001, 2003, 2004 Petr Baudis <pasky@ucw.cz>
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 2, as published by the
@ -30,7 +30,9 @@
use strict;
use vars qw ($project $repository $from_email $dest_email $reply_email
$CVS $cvsweb_url $help_msg $sync_delay $x_mailer);
$CVS $diffstat $cvsweb_url $help_msg $sync_delay $max_diff_lines
$show_diffstat $show_diff $login $subj_files $subj_maxlength
$withthreading_email $messageid_email $mail_contenttype $mail_contenttransen);
@ -38,10 +40,7 @@ use vars qw ($project $repository $from_email $dest_email $reply_email
### Configuration
# Project name.
$project = 'TLDP';
# X-mailer for better identification
$x_mailer = '$Id$';
$project = 'LDP';
# The path to the repository. If your platform or CVS implementation doesn't
# pass the full path to the cvslog script in $0 (or if your cvslog script
@ -51,22 +50,44 @@ $x_mailer = '$Id$';
$repository = '/cvsroot'; # ($0 =~ m#^(.*)/CVSROOT/cvslog$#);
# The from address in the generated mails.
$from_email = 'ser@tldp.org';
$login = $ENV{'CVS_USER'} || $ENV{'CVS_USERNAME'} || $ENV{'CVSUSER'} ||
getlogin || (getpwuid($<))[0] || "nobody";
$from_email = "$login <$login\@tldp.org>";
# Mail all reports to this address.
#$dest_email = 'elinks-cvs@v.or.cz, pasky@pasky.ji.cz, fonseca@diku.dk, zas@norz.org';
$dest_email = 'cvs-commits@en.tldp.org';
$dest_email = 'cvs-commit@tldp.org';
# Email address all the replies should go at.
$reply_email = 'discuss@en.tldp.org';
# suffix of Message-ID in email header
$messageid_email = '@tldp.org';
# with threading?
$withthreading_email = 1;
# mail content-type
$mail_contenttype="text/plain; charset=iso-8859-1";
# mail content-transfer-encoding
$mail_contenttransen="8bit";
# The cvs binary location + name (full path to the executable). If in doubt,
# try just 'cvs' and hope. Otherwise, /usr/bin/cvs or /usr/local/bin/cvs could
# do.
$CVS = '/usr/bin/cvs';
# The diffstat binary location + name (full path to the executable) plus the
# additional arguments you want to pass to it. If in doubt, keep the default
# arguments and try just 'diffstat' and hope. Otherwise, /usr/bin/diffstat or
# /usr/local/bin/diffstat could do. Just comment it out if you don't have
# diffstat enabled.
$diffstat = '/usr/bin/diffstat -p0 -w 72';
# URL of cvsweb. Just comment out if you don't have any.
$cvsweb_url = 'http://cvsview.tldp.org/index.cgi';
$cvsweb_url = 'http://cvsview.tldp.org';
# The leading message of the mail:
$help_msg = "This is an automated notification of a change to the $project CVS tree.";
@ -78,8 +99,23 @@ $help_msg = "This is an automated notification of a change to the $project CVS t
# directories.
$sync_delay = 5;
# Maximal number of lines the diff can contain. If it will be longer, it is
# going to be trimmed to this length.
# Assuming that each line is avg. 60 lines long and we don't want to have mails
# bigger than 35kb, the maximal number of lines would be 597.
$max_diff_lines = 597;
# Whether you want the diffstat of changes to be sent in the message.
$show_diffstat = 0;
# Whether you want the diff of changes to be sent in the message.
$show_diff = 1;
# Whether you want the affected files list in subject
$subj_files=1;
# How long the subject can be
$subj_maxlength=78;
### The code itself
@ -145,14 +181,13 @@ while (<STDIN>) {
}
}
$htag = $tag ? $tag : "<TRUNK>";
$htag = $tag ? $tag : "HEAD";
while (<STDIN>) {
$logmsg .= $_;
}
### Check if we want to waste time at this whole thing at all
@ -186,7 +221,7 @@ if (-f $syncfile and -w $syncfile) {
push (@t, join(',', $_->{name}, $_->{oldrev}, $_->{newrev}, $_->{op}));
}
print FF join(' ', $dirs[0]->{name}, $dirs[0]->{type}, @t) . "\n";
print FF join("\t", $dirs[0]->{name}, $dirs[0]->{type}, @t) . "\n";
}
close (FF);
@ -212,7 +247,7 @@ if (-f $syncfile and -w $syncfile) {
while (<FF>) {
chomp;
my ($zdir, $ztype, @zfiles) = split (' ');
my ($zdir, $ztype, @zfiles) = split ("\t");
$dirs[$i]->{name} = $zdir;
$dirs[$i]->{type} = $ztype;
@ -236,7 +271,7 @@ if (-f $syncfile and -w $syncfile) {
# Open our mail program
open (MAIL, '| /var/qmail/bin/sendmail -t -oi -oem')
open (MAIL, '| /usr/lib/sendmail -t -oi -oem')
or die "$0: cannot fork sendmail: $!\n";
@ -246,12 +281,6 @@ my ($date);
$date = scalar gmtime;
# Fill in subj and possibly cut it
my ($subj);
$subj = "Subject: [$project] $module".($tag?" ($tag)":"")." - $user: $logmsg";
$subj =~ s/\n/ /g; $subj =~ s/ *$//;
$subj = substr($subj, 0, 75) . '...' if (length($subj) > 78);
# Compose the mail
@ -259,78 +288,120 @@ $subj = substr($subj, 0, 75) . '...' if (length($subj) > 78);
# TODO: Use CVSROOT/users to determine the committer's realname and email and
# add it to the reply-to / mail-followup-to list. --pasky
my ($VERSION) = '$Revision$' =~ / (\d+\.\d+) /;
# Subject files, references and
# future "files affected part" (List the files being changed, plus the cvsweb URLs)
my $files_affected_part="";
my $subj_file_list="";
my $references="";
my $messageid="";
my $cvsweb_part="";
for (my $i = 0; $i < @dirs; $i++) {
my $dirs = $dirs[$i];
my $dir = $dirs->{name};
my $subdir = $dir;
$subdir =~ s!^[^/]*/?!!;
$subdir .= '/' if $subdir ne '';
$files_affected_part .= "\n$dir:\n ";
if ($dirs[$i]->{type} eq 'directory') {
$files_affected_part .= "New directory\n";
} else {
my $commits = $dirs->{commits};
for (my $j = 0; $j < @$commits; $j++) {
my $ref;
my $commit = $commits->[$j];
my ($name, $oldrev, $newrev, $op) = ("NAME","NONE","NONE",-1);
($name, $oldrev, $newrev, $op) = ($commit->{name}, $commit->{oldrev}, $commit->{newrev}, $commit->{op});
$subj_file_list .= "$subdir$name";
$subj_file_list .= " (NEW)" if ($op eq 'add');
$subj_file_list .= " (REMOVED)" if ($op eq 'remove');
$subj_file_list .= ", ";
$files_affected_part .= "$name ($oldrev -> $newrev) ";
$files_affected_part .= " (NEW)" if ($op eq 'add');
$files_affected_part .= " (REMOVED)" if ($op eq 'remove');
$files_affected_part .= " (?! contact devils)" if ($op eq '?');
$files_affected_part .= ", " if $j < @$commits-1;
# $files_affected_part .= "\n";
$cvsweb_part .= " $cvsweb_url/$dir/$name?r1=$oldrev&r2=$newrev&f=u\n"
if defined $cvsweb_url and $op ne 'add' and $op ne 'remove';
$ref=$dir."_".$name.".".$newrev;
$ref =~ s/[^a-zA-Z0-9.]/_/g;
$messageid="<".$ref.$messageid_email.">";
$ref=$dir."_".$name.".".$oldrev;
$ref =~ s/[^a-zA-Z0-9.]/_/g;
$references.=" <". $ref. $messageid_email .">";
}
}
}
# Fill in subj and possibly cut it
my ($subj);
$subj_file_list =~ s/, $/ /;
$subj = "Subject: $module".($tag?" ($tag)":"").": ".($subj_files?$subj_file_list:"").$logmsg;
$subj =~ s/\n/ /g; $subj =~ s/ *$//;
$subj = substr($subj, 0, $subj_maxlength-3) . '...' if (length($subj) > $subj_maxlength);
my $keywords="DEV-$user, MOD-$module, TAG-".($tag?$tag:"HEAD").", ". $subj_file_list;
print MAIL <<EOM;
From: $from_email
To: $dest_email
Reply-To: $reply_email
Mail-Followup-To: $reply_email
X-CVS: $user\@$project:$module
X-Mailer: $x_mailer
X-CVS-Module: $module
User-Agent: cvslog.pl/$VERSION
$subj
$help_msg
Author: $user
Module: $module
Tag: $htag
Date: $date GMT
Message-ID: $messageid
MIME-Version: 1.0
Content-Transfer-Encoding: $mail_contenttransen
Content-Type: $mail_contenttype
Keywords: $keywords
EOM
if ($withthreading_email) {
print MAIL <<EOM;
References: $references
In-Reply-To: $references
EOM
}
my $msgheader = sprintf ("%-36s %s\n%-36s %s", "Author: $user", "Date: $date GMT","Module: $module"," Tag: $htag");
$logmsg =~ s/\n+/\n/gm;
print MAIL <<EOM;
---- Log message:
$msgheader
EOM
print MAIL <<EOM;
---- Log message:
$logmsg
EOM
print MAIL <<EOM;
---- Files affected:
---- Files affected:$files_affected_part
EOM
# List the files being changed, plus the cvsweb URLs
for (my $i = 0; $i < @dirs; $i++) {
my $dirs = $dirs[$i];
my $dir = $dirs->{name};
print MAIL "$dir:\n";
if ($dirs[$i]->{type} eq 'directory') {
print MAIL " New directory\n";
} else {
my $commits = $dirs->{commits};
for (my $j = 0; $j < @$commits; $j++) {
my $commit = $commits->[$j];
my ($name, $oldrev, $newrev, $op) = ($commit->{name}, $commit->{oldrev}, $commit->{newrev}, $commit->{op});
print MAIL " $name ($oldrev -> $newrev) ";
print MAIL " (new)" if ($op eq 'add');
print MAIL " (removed)" if ($op eq 'remove');
print MAIL " (?! contact pasky)" if ($op eq '?');
print MAIL "\n";
print MAIL " $cvsweb_url/$dir/$name.diff?r1=$oldrev&r2=$newrev&f=u\n"
if defined $cvsweb_url and $op ne 'add' and $op ne 'remove';
}
}
}
goto end_diff unless $show_diff or $show_diffstat;
print MAIL <<EOM;
---- Diffs:
EOM
# And now the diffs!
# TODO: Show always diffstat first. --pasky
# TODO: If the diff itself is over N lines, show only the diffstat. --pasky
my @diff;
for (my $i = 0; $i < @dirs; $i++) {
my $dirs = $dirs[$i];
@ -350,13 +421,6 @@ for (my $i = 0; $i < @dirs; $i++) {
# Do not print diffs of removed files. Too boring.
next if ($newrev eq 'NONE');
# XXX: Diffs of .po files are too big.
if ($name =~ /\.po$/) {
print MAIL "Index: $dir/$name\n";
print MAIL "<<Some probably quite big and messy diff>>\n";
next;
}
my @difflines;
my $pid = open (CVS, '-|');
@ -375,12 +439,59 @@ for (my $i = 0; $i < @dirs; $i++) {
}
}
print MAIL @difflines;
push (@diff, "\n" . ("=" x 64) . "\n");
push (@diff, @difflines);
}
}
push (@diff, ("=" x 64) . "\n");
# Diffstat
my $dstmp = '/tmp/cvslog.diffstat.'.$$;
if ($diffstat and $show_diffstat and open (DSTMP, '>' . $dstmp)) {
print DSTMP @diff;
close DSTMP;
my $pid = open (DIFFSTAT, '-|');
if (!defined $pid) {
die "$0: can't fork diffstat: $!\n";
} elsif ($pid == 0) {
open (STDERR, '>&STDOUT') or die "$0: can't reopen stderr: $!\n";
exec (split(/\s+/, $diffstat), $dstmp)
or die "$0: can't fork diffstat: $!\n";
} else {
my @diffstat = <DIFFSTAT>;
close DIFFSTAT;
print MAIL @diffstat;
print MAIL "\n";
}
unlink ($dstmp);
}
goto end_diff unless $show_diff;
if (@diff > $max_diff_lines) {
@diff = splice(@diff, 0, $max_diff_lines);
print MAIL @diff;
print MAIL "<<Diff was trimmed, longer than $max_diff_lines lines>>\n";
} else {
print MAIL @diff;
}
end_diff:
if ($cvsweb_part ne ""){
print MAIL <<EOM;
---- CVS-web:
$cvsweb_part
EOM
}
# Send it to the world
close MAIL;
die "$0: sendmail exit status " . $? >> 8 . "\n" unless ($? == 0);
# vi: set sw=2: