diff options
author | Martin Schulze <joey@infodrom.org> | 2004-08-09 18:06:17 +0200 |
---|---|---|
committer | Martin Schulze <joey@infodrom.org> | 2004-08-09 18:06:17 +0200 |
commit | 443c32442d049763ec8cc6aa35333bbe241bc9b4 (patch) | |
tree | f2ed391ba86bf0386a72877ede020aa480673e2c /cvs-mailcommit |
Import cvs-mailcommit_1.19.orig.tar.gz
[dgit import orig cvs-mailcommit_1.19.orig.tar.gz]
Diffstat (limited to 'cvs-mailcommit')
-rwxr-xr-x | cvs-mailcommit | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/cvs-mailcommit b/cvs-mailcommit new file mode 100755 index 0000000..dde1677 --- /dev/null +++ b/cvs-mailcommit @@ -0,0 +1,393 @@ +#! /usr/bin/perl + +# cvs-mailcommit - Send CVS commitments via mail +# Copyright (c) 1998,2004 Martin Schulze <joey@infodrom.org> +# +# $Id: cvs-mailcommit,v 1.19 2004/08/09 15:48:09 joey Exp $ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + +# For testing, call this program like: +# echo "Logmsg" | CVSROOT=/cvs/webwml ./cvs-mailcommit -m $LOGNAME --from "$LOGNAME@`hostname -f`" --cvs 'CVSROOT loginfo,1.10,1.11' --diff + +# To extract the inline documentation, run the following command: +# pod2html cvs-mailcommit > cvs-mailcommit.1 +# To read this documentation, just type +# perldoc cvs-mailcommit + +use Getopt::Long; + +=head1 NAME + +cvs-mailcommit - Send CVS commitments via mail + +=head1 SYNOPSIS + +B<cvs-mailcommit> [options] [version*] + +=head1 DESCRIPTION + +B<cvs-mailcommit> is a helper application to CVS to help people keep +track of CVS repositories via mail. It is hooked into the CVS system +via the B<CVSROOT>/I<loginfo> file. It will read modification +information from CVS via B<stdin> and require version information via +the commandline. + +B<cvs-mailcommit> will send differences of modified files or entire +new files via mail to the denoted address. + +You'll have to hook it into CVS for each module in a repository that +you want to monitor via mail. See B<INSTALLATION> below + +=cut + +$sendmail = "/usr/lib/sendmail"; +$rcsdiff = "rcsdiff"; +$co = "co"; + +$opt_xloop = ''; +$opt_cvs = ''; +$opt_from = ''; +$opt_replyto = ''; +$opt_approved = ''; +$opt_diff = 0; +$opt_full = 0; +$opt_maxlines = 400; +@opt_mailto = (); +$opt_cvsroot = ''; +$opt_dir = ''; + +# A way to alter the default settings +$cfg = "/etc/cvs-mailcommit.pl"; +require $cfg if (-r $cfg); + +my %options = ( + 'mailto|m=s' => \@opt_mailto, + 'diff|d' => \$opt_diff, + 'full' => \$opt_full, + 'xloop=s' => \$opt_xloop, + 'from=s' => \$opt_from, + 'replyto=s' => \$opt_replyto, + 'approved=s' => \$opt_approved, + 'maxlines=i' => \$opt_maxlines, + 'cvs=s' => \$opt_cvs, + 'root=s' => \$opt_cvsroot, + 'dir=s' => \$opt_dir, + ); + +# Filter out new directory creations +# Arguments: '- New directory' NONE NONE +# +$pivot = 0; +while ($pivot <= $#ARGV) { + splice (@ARGV, $pivot, $pivot+2) if ($ARGV[$pivot] eq '- New directory'); + $pivot++; +} + +GetOptions (%options); + +=head1 OPTIONS + +This program supports the following arguments. When the arguments +don't make sense the program won't do anything. + +=over 6 + +=item B<-m> I<address>, B<--mailto> I<address> + +Send the mail to the specified I<address>. This option can be +specified on the commandline multiple times. + +=item B<--diff> + +Generate unified diffs for all modified files. + +=item B<--full> + +Include the entire fill for newly created files that were added to the +repository. + +=item B<--maxlines> I<nnn> + +You can specify how many lines per file may be quoted in the resulting +mail. Limiting the number of quoted lines may be useful for +repositories with excessive changes that are similar. The default is +to copy 400 lines. + +=item B<--xloop> I<address> + +Include a special B<X-Loop> header in the generated mail. This is +intended for users to be able to filter CVS mails by a common header +line. The line will look like + +X-Loop: I<address> + +=item B<--from> I<address> + +Generate a B<From:>-line of the form + +From: CVS User foo <I<address>> + +Otherwise the local user the program runs under will be used instead +of I<address>. With this parameter you can ensure that all such mails +will be sent with the same from line, which may be useful for +moderated lists or some where only subscribers may write. + +=item B<--replyto> I<address> + +Try to redirect replies to CVS mails to another address by setting +proper header lines such as + +Reply-To: I<address> + +Mail-Followup-To: I<address> + +=item B<--approved> I<address> + +Include a special B<Approved:>-line in the mail. This header is +intended for moderated mailing-lists to pass the SmartList moderation +mechanism. The created header will look like + +Approved: I<address> + +=item B<--cvs> I<version string> + +This option carries the CVS version info from CVS into the program. +It will be added automatically by CVS. When installing this program +into the B<loginfo> file of a CVS repository, you will need to add the +following option: + +B<--cvs> %{sVv} + +If you want to test this program manually you'll have to supply the +module directory and the modified files including the old and new +versions. This will look like + +--cvs 'CVSROOT loginfo,1.1,1.2' + +This option is only usful for old-style CVS format strings (i.e. prior +to CVS 1.12.6). You can continue using old-style format strings with +newer cvs if you write %1{sVv} and set B<UseNewInfoFmtStrings>=I<yes> +in CVSROOT/config. For more recent versions of CVS you should, +however, use the new --root and --dir arguments and place %{sVv} at +the end of the commandline. + +=item B<--root> I<cvs repository> + +Specify the CVS repository directory. This is normally done by the +CVS server. Prior to version 1.12 the repository was transmitted to +the log processor via the B<CVSROOT> environment variable. The +parameter to this option is normally filled in by CVS using the %r +format string: + +B<--root> %r + +=item B<--dir> I<module directory> + +Specify the directory within the CVS repository in which directories +or file were added or modified. The parameter to this option is +normally filled in by CVS using the %p format string: + +B<--dir> %p + +=back + +=cut + +exit 0 if (!@opt_mailto); + +# $opt_cvs looks like +# foo/waz bar,1.4,1.5 foo,1.2,1.3 +# or +# foo gnatz,1.3,1.4 +# +if ($opt_cvs) { + @cvs_arr = split (/ /,$opt_cvs); + $opt_dir = $cvs_arr[0]; + $module_dir = $ENV{'CVSROOT'} . "/" . shift(@cvs_arr); +} else { + if ($opt_cvsroot) { + if ($opt_dir) { + $module_dir = $opt_cvsroot ."/". $opt_dir; + } else { + $module_dir = $opt_cvsroot; + } + while ($#ARGV >= 2) { + push (@cvs_arr, shift (@ARGV) .",". shift (@ARGV) .",". shift (@ARGV)); + } + while ($#ARGV > -1) { + printf "Unknown argument '%s', deleting.\n", shift (@ARGV); + } + } else { + print STDERR "No --cvs and no --root (and --dir) specified, aborting.\n"; + } +} + +$login = $ENV{'CVS_USER'} || $ENV{'LOGNAME'}|| getlogin || (getpwuid($<))[0] || "nobody"; +$logname = $ENV{'LOGNAME'}|| getlogin || (getpwuid($<))[0] || $ENV{'CVS_USER'} || "nobody"; + +if (open (M, "|$sendmail -t")) { +# if (open (M, ">-")) { + printf M "To: %s\n", join(",",@opt_mailto); + printf M "Subject: CVS %s\n", $opt_dir; + if ($opt_from) { + printf M "From: \"CVS User %s\" <%s>\n", $login, $opt_from; + } else { + printf M "From: \"CVS User %s\" <%s>\n", $login, $logname; + } + if ($opt_replyto) { + printf M "Reply-To: %s\n", $opt_replyto; + printf M "Mail-Followup-To: %s\n", $opt_replyto; + } + printf M "Approved: %s\n", $opt_approved if ($opt_approved); + printf M "X-Loop: %s\n", $opt_xloop if ($opt_xloop); + print M "\n"; + print M while (<>); + + if ($opt_diff) { + print M "\n"; + foreach $cstr (@cvs_arr) { + ($file,$oldver,$newver) = split (/,/,$cstr); + next if ($oldver eq "" || $newver eq ""); + if ($oldver ne "NONE") { + # print "$rcsdiff -r$oldver -r$newver -u $module_dir/$file|\n"; + if (open (R, "$rcsdiff -r$oldver -r$newver -u $module_dir/$file 2>/dev/null |")) { + $lines = 0; + while (<R>) { + $lines++; + print M if ($lines <= $opt_maxlines); + } + close (R); + printf M "\n[%d lines skipped]\n", $lines - $opt_maxlines if ($lines > $opt_maxlines); + } + } + } + } + + # Process new files + if ($opt_full) { + print M "\n"; + foreach $cstr (@cvs_arr) { + ($file,$oldver,$newver) = split (/,/,$cstr); + next if ($oldver ne "NONE" || $newver ne "1.1"); + + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) + = gmtime(time); + + my $date = sprintf ("%4d/%02d/%02d %02d:%02d:%02d", + $year+1900, $mon+1, $mday, $hour,$min,$sec); + + if (open (R, "$co -p -r$newver $module_dir/$file 2>/dev/null |")) { + printf M "--- %s/%s\t%s\tNONE\n", $module_dir, $file, $date; + printf M "+++ %s/%s\t%s\t%s\n", $module_dir, $file, $date, $newver; + while (<R>) { + $lines++; + print M if ($lines <= $opt_maxlines); + } + close (R); + printf M "\n[%d lines skipped]\n", $lines - $opt_maxlines if ($lines > $opt_maxlines); + } else { + print M "Cannot open $co, huh, $!\n"; + } + } + } + + close (M); +} + +=head1 CONFIGURATION FILE + +B<cvs-mailcommit> supports an additional configuration file +I</etc/cvs-mailcommit.pl> so that hard-coded default values can be +overwritten. The file is included via require and hence needs to +contain valid Perl code, which evaluates to I<true>. I.e. place B<1;> +at the end of the file. + +=head1 INSTALLATION + +The B<CVSROOT>/I<loginfo> file controls where B<cvs commit> log +information is sent. The first entry on a line is a regular +expression which must match the directory (alias module) that the +change is being made to, relative to the $B<CVSROOT>. If a match is +found, then the remainder of the line is a filter program that should +expect log information on its standard input. + +A I<loginfo> line looks like + +<directory> <command> --<option> --<option> + +=head1 NOTES + +The B<--cvs> option is only valid for old-style CVS format strings +prior to version 1.12.6 of CVS with I<%{sVv}> or for new-style CVS +format strings using the compatibility hack with I<%1{sVv}>. + +For new-style CVS format strings for CVS version 1.12.6 or higher +B<--cvs> must not be used anymore, but instead B<--root> and B<--dir> +are required. The version information I<%{sVv}> must be added at the +end of the command line. + +=head1 EXAMPLE + +Assume you want to monitor changes in the B<CVSROOT> module, then you +may want to use the following line. + + CVSROOT cvs-mailcommit \ + --mailto master@host.org \ + --from cvs@cvshost.com \ + --cvs %{sVv} --diff --full + +If you want to distribute changes in a module via a mailing list where +only these log messages should appear you may have to add an X-Loop: +or Approved: header line. + + webwml cvs-mailcommit \ + --mailto master@host.org \ + --from cvs@cvshost.com \ + --approved cvsmaster@cvshost.com \ + --cvs %{sVv} --diff --full + +The above configuration lines are valid only for old-style format +strings. With a more recent version of CVS (1.12.6 or newer) you'll +have to replace I<%{sVv}> with I<%1{sVv}> and set +B<UseNewInfoFmtStrings> to I<yes> in I<CVSROOT/config>. + +For new-style CVS format strings other parameters need to be used +since CVS changed the syntax and semantics. You must not use the +B<--cvs> option anymore but need to use B<--root> and B<--dir> and +place the version list at the end. The last example converted for +new-style format strings looks like the following: + + webwml cvs-mailcommit \ + --mailto master@host.org \ + --from cvs@cvshost.com \ + --approved cvsmaster@cvshost.com \ + --diff --full --root %r --dir %p %{sVv} + +To improve readability, the above lines were broken up into several +lines using normal continuation lines. This is not supported by CVS. +You will have to write it in one single line. + +=head1 WARNING + +CVS does not support continuation lines (multiple lines per command) +in the B<CVSROOT>/I<loginfo> file. You'll have to write each filter +in a single line of its own. + +=head1 SOURCE + +http://www.infodrom.org/Infodrom/tools/cvs-mailcommit.html + +=cut |