summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/contrib/log_accum.in
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/contrib/log_accum.in')
-rwxr-xr-xcontrib/cvs/contrib/log_accum.in956
1 files changed, 550 insertions, 406 deletions
diff --git a/contrib/cvs/contrib/log_accum.in b/contrib/cvs/contrib/log_accum.in
index 8591784..f8d624c 100755
--- a/contrib/cvs/contrib/log_accum.in
+++ b/contrib/cvs/contrib/log_accum.in
@@ -9,419 +9,602 @@
# This file assumes a pre-commit checking program that leaves the
# names of the first and last commit directories in a temporary file.
#
+# IMPORTANT: what the above means is, this script interacts with
+# commit_prep, in that they have to agree on the tmpfile name to use.
+# See $LAST_FILE below.
+#
+# How this works: CVS triggers this script once for each directory
+# involved in the commit -- in other words, a single commit can invoke
+# this script N times. It knows when it's on the last invocation by
+# examining the contents of $LAST_FILE. Between invocations, it
+# caches information for its future incarnations in various temporary
+# files in /tmp, which are named according to the process group and
+# the committer (by themselves, neither of these are unique, but
+# together they almost always are, unless the same user is doing two
+# commits simultaneously). The final invocation is the one that
+# actually sends the mail -- it gathers up the cached information,
+# combines that with what it found out on this pass, and sends a
+# commit message to the appropriate mailing list.
+#
+# (Ask Karl Fogel <kfogel@collab.net> if questions.)
+#
# Contributed by David Hampton <hampton@cisco.com>
+# Roy Fielding removed useless code and added log/mail of new files
+# Ken Coar added special processing (i.e., no diffs) for binary files
#
-# hacked greatly by Greg A. Woods <woods@planix.com>
-
-# Usage: log_accum.pl [-d] [-s] [-w] [-M module] [-u user] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
-# -d - turn on debugging
-# -m mailto - send mail to "mailto" (multiple)
-# -R replyto - set the "Reply-To:" to "replyto" (multiple)
-# -M modulename - set module name to "modulename"
-# -f logfile - write commit messages to logfile too
-# -s - *don't* run "cvs status -v" for each file
-# -w - show working directory with log message
-# -u user - $USER passed from loginfo
+############################################################
#
-# Configurable options
+# Configurable options
#
-
-# set this to something that takes a whole message on stdin
-$MAILER = "/usr/lib/sendmail -t";
-
+############################################################
+#
+# Where do you want the RCS ID and delta info?
+# 0 = none,
+# 1 = in mail only,
+# 2 = in both mail and logs.
#
-# End user configurable options.
+$rcsidinfo = 2;
+
+#if you are using CVS web then set this to some value... if not set it to ""
#
+# When set properly, this will cause links to aspects of the project to
+# print in the commit emails.
+#$CVSWEB_SCHEME = "http";
+#$CVSWEB_DOMAIN = "cvshome.org";
+#$CVSWEB_PORT = "80";
+#$CVSWEB_URI = "source/browse/";
+#$SEND_URL = "true";
+$SEND_DIFF = "true";
+
+
+# Set this to a domain to have CVS pretend that all users who make
+# commits have mail accounts within that domain.
+#$EMULATE_LOCAL_MAIL_USER="cvshome.org";
-# Constants (don't change these!)
+# Set this to '-c' for context diffs; defaults to '-u' for unidiff format.
+$difftype = '-uN';
+
+############################################################
+#
+# Constants
#
+############################################################
$STATE_NONE = 0;
$STATE_CHANGED = 1;
$STATE_ADDED = 2;
$STATE_REMOVED = 3;
$STATE_LOG = 4;
-$LAST_FILE = "/tmp/#cvs.lastdir";
+$TMPDIR = $ENV{'TMPDIR'} || '/tmp';
+$FILE_PREFIX = '#cvs.';
-$CHANGED_FILE = "/tmp/#cvs.files.changed";
-$ADDED_FILE = "/tmp/#cvs.files.added";
-$REMOVED_FILE = "/tmp/#cvs.files.removed";
-$LOG_FILE = "/tmp/#cvs.files.log";
+$LAST_FILE = "$TMPDIR/${FILE_PREFIX}lastdir"; # Created by commit_prep!
+$ADDED_FILE = "$TMPDIR/${FILE_PREFIX}files.added";
+$REMOVED_FILE = "$TMPDIR/${FILE_PREFIX}files.removed";
+$LOG_FILE = "$TMPDIR/${FILE_PREFIX}files.log";
+$BRANCH_FILE = "$TMPDIR/${FILE_PREFIX}files.branch";
+$MLIST_FILE = "$TMPDIR/${FILE_PREFIX}files.mlist";
+$SUMMARY_FILE = "$TMPDIR/${FILE_PREFIX}files.summary";
-$FILE_PREFIX = "#cvs.files";
+$CVSROOT = $ENV{'CVSROOT'};
+$MAIL_CMD = "| /usr/lib/sendmail -i -t";
+#$MAIL_CMD = "| /var/qmail/bin/qmail-inject";
+$MAIL_FROM = 'commitlogger'; #not needed if EMULATE_LOCAL_MAIL_USER
+$SUBJECT_PRE = 'CVS update:';
+
+
+############################################################
#
-# Subroutines
+# Subroutines
#
+############################################################
+
+sub format_names {
+ local($dir, @files) = @_;
+ local(@lines);
+
+ $lines[0] = sprintf(" %-08s", $dir);
+ foreach $file (@files) {
+ if (length($lines[$#lines]) + length($file) > 60) {
+ $lines[++$#lines] = sprintf(" %8s", " ");
+ }
+ $lines[$#lines] .= " ".$file;
+ }
+ @lines;
+}
sub cleanup_tmpfiles {
- local($wd, @files);
+ local(@files);
- $wd = `pwd`;
- chdir("/tmp") || die("Can't chdir('/tmp')\n");
- opendir(DIR, ".");
- push(@files, grep(/^$FILE_PREFIX\..*\.$id$/, readdir(DIR)));
+ opendir(DIR, $TMPDIR);
+ push(@files, grep(/^${FILE_PREFIX}.*\.${id}\.${cvs_user}$/, readdir(DIR)));
closedir(DIR);
foreach (@files) {
- unlink $_;
+ unlink "$TMPDIR/$_";
}
- unlink $LAST_FILE . "." . $id;
-
- chdir($wd);
}
sub write_logfile {
local($filename, @lines) = @_;
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
+ open(FILE, ">$filename") || die ("Cannot open log file $filename: $!\n");
+ print(FILE join("\n", @lines), "\n");
close(FILE);
}
-sub append_to_logfile {
- local($filename, @lines) = @_;
+sub append_to_file {
+ local($filename, $dir, @files) = @_;
- open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
- print FILE join("\n", @lines), "\n";
- close(FILE);
+ if (@files) {
+ local(@lines) = &format_names($dir, @files);
+ open(FILE, ">>$filename") || die ("Cannot open file $filename: $!\n");
+ print(FILE join("\n", @lines), "\n");
+ close(FILE);
+ }
}
-sub format_names {
- local($dir, @files) = @_;
- local(@lines);
+sub write_line {
+ local($filename, $line) = @_;
- $format = "\t%-" . sprintf("%d", length($dir)) . "s%s ";
+ open(FILE, ">$filename") || die("Cannot open file $filename: $!\n");
+ print(FILE $line, "\n");
+ close(FILE);
+}
- $lines[0] = sprintf($format, $dir, ":");
+sub append_line {
+ local($filename, $line) = @_;
- if ($debug) {
- print STDERR "format_names(): dir = ", $dir, "; files = ", join(":", @files), ".\n";
- }
- foreach $file (@files) {
- if (length($lines[$#lines]) + length($file) > 65) {
- $lines[++$#lines] = sprintf($format, " ", " ");
- }
- $lines[$#lines] .= $file . " ";
- }
-
- @lines;
+ open(FILE, ">>$filename") || die("Cannot open file $filename: $!\n");
+ print(FILE $line, "\n");
+ close(FILE);
}
-sub format_lists {
- local(@lines) = @_;
- local(@text, @files, $lastdir);
+sub read_line {
+ local($filename) = @_;
+ local($line);
+
+ open(FILE, "<$filename") || die("Cannot open file $filename: $!\n");
+ $line = <FILE>;
+ close(FILE);
+ chomp($line);
+ $line;
+}
- if ($debug) {
- print STDERR "format_lists(): ", join(":", @lines), "\n";
- }
- @text = ();
- @files = ();
- $lastdir = shift @lines; # first thing is always a directory
- if ($lastdir !~ /.*\/$/) {
- die("Damn, $lastdir doesn't look like a directory!\n");
- }
- foreach $line (@lines) {
- if ($line =~ /.*\/$/) {
- push(@text, &format_names($lastdir, @files));
- $lastdir = $line;
- @files = ();
- } else {
- push(@files, $line);
- }
- }
- push(@text, &format_names($lastdir, @files));
+sub read_line_nodie {
+ local($filename) = @_;
+ local($line);
+ open(FILE, "<$filename") || return ("");
- @text;
+ $line = <FILE>;
+ close(FILE);
+ chomp($line);
+ $line;
}
-sub append_names_to_file {
- local($filename, $dir, @files) = @_;
+sub read_file_lines {
+ local($filename) = @_;
+ local(@text) = ();
- if (@files) {
- open(FILE, ">>$filename") || die("Cannot open file $filename.\n");
- print FILE $dir, "\n";
- print FILE join("\n", @files), "\n";
- close(FILE);
+ open(FILE, "<$filename") || return ();
+ while (<FILE>) {
+ chomp;
+ push(@text, $_);
}
+ close(FILE);
+ @text;
}
-sub read_line {
- local($line);
- local($filename) = @_;
+sub read_file {
+ local($filename, $leader) = @_;
+ local(@text) = ();
- open(FILE, "<$filename") || die("Cannot open file $filename.\n");
- $line = <FILE>;
+ open(FILE, "<$filename") || return ();
+ while (<FILE>) {
+ chomp;
+ push(@text, sprintf(" %-10s %s", $leader, $_));
+ $leader = "";
+ }
close(FILE);
- chop($line);
- $line;
+ @text;
}
sub read_logfile {
- local(@text);
local($filename, $leader) = @_;
+ local(@text) = ();
- open(FILE, "<$filename");
+ open(FILE, "<$filename") || die ("Cannot open log file $filename: $!\n");
while (<FILE>) {
- chop;
- push(@text, $leader.$_);
+ chomp;
+ push(@text, $leader.$_);
}
close(FILE);
@text;
}
+#
+# do an 'cvs -Qn status' on each file in the arguments, and extract info.
+#
+sub change_summary {
+ local($out, @filenames) = @_;
+ local(@revline);
+ local($file, $rev, $rcsfile, $line, $vhost, $cvsweb_base);
+
+ while (@filenames) {
+ $file = shift @filenames;
+
+ if ("$file" eq "") {
+ next;
+ }
+
+ open(RCS, "-|") || exec "$cvsbin/cvs", '-Qn', 'status', '--', $file;
+
+ $rev = "";
+ $delta = "";
+ $rcsfile = "";
+
+
+ while (<RCS>) {
+ if (/^[ \t]*Repository revision/) {
+ chomp;
+ @revline = split(' ', $_);
+ $rev = $revline[2];
+ $rcsfile = $revline[3];
+ $rcsfile =~ s,^$CVSROOT/,,;
+ $rcsfile =~ s/,v$//;
+ }
+ }
+ close(RCS);
+
+
+ if ($rev ne '' && $rcsfile ne '') {
+ open(RCS, "-|") || exec "$cvsbin/cvs", '-Qn', 'log', "-r$rev",
+ '--', $file;
+ while (<RCS>) {
+ if (/^date:/) {
+ chomp;
+ $delta = $_;
+ $delta =~ s/^.*;//;
+ $delta =~ s/^[\s]+lines://;
+ }
+ }
+ close(RCS);
+ }
+
+ $diff = "\n\n";
+ $vhost = @path[0];
+ if ($CVSWEB_PORT eq "80") {
+ $cvsweb_base = "$CVSWEB_SCHEME://$vhost.$CVSWEB_DOMAIN/$CVSWEB_URI";
+ }
+ else {
+ $cvsweb_base = "$CVSWEB_SCHEME://$vhost.$CVSWEB_DOMAIN:$CVSWEB_PORT/$CVSWEB_URI";
+ }
+ if ($SEND_URL eq "true") {
+ $diff .= $cvsweb_base . join("/", @path) . "/$file";
+ }
+
+ #
+ # If this is a binary file, don't try to report a diff; not only is
+ # it meaningless, but it also screws up some mailers. We rely on
+ # Perl's 'is this binary' algorithm; it's pretty good. But not
+ # perfect.
+ #
+ if (($file =~ /\.(?:pdf|gif|jpg|mpg)$/i) || (-B $file)) {
+ if ($SEND_URL eq "true") {
+ $diff .= "?rev=$rev&content-type=text/x-cvsweb-markup\n\n";
+ }
+ if ($SEND_DIFF eq "true") {
+ $diff .= "\t<<Binary file>>\n\n";
+ }
+ }
+ else {
+ #
+ # Get the differences between this and the previous revision,
+ # being aware that new files always have revision '1.1' and
+ # new branches always end in '.n.1'.
+ #
+ if ($rev =~ /^(.*)\.([0-9]+)$/) {
+ $prev = $2 - 1;
+ $prev_rev = $1 . '.' . $prev;
+
+ $prev_rev =~ s/\.[0-9]+\.0$//;# Truncate if first rev on branch
+
+ if ($rev eq '1.1') {
+ if ($SEND_URL eq "true") {
+ $diff .= "?rev=$rev&content-type=text/x-cvsweb-markup\n\n";
+ }
+ if ($SEND_DIFF eq "true") {
+ open(DIFF, "-|")
+ || exec "$cvsbin/cvs", '-Qn', 'update', '-p', '-r1.1',
+ '--', $file;
+ $diff .= "Index: $file\n=================================="
+ . "=================================\n";
+ }
+ }
+ else {
+ if ($SEND_URL eq "true") {
+ $diff .= ".diff?r1=$prev_rev&r2=$rev\n\n";
+ }
+ if ($SEND_DIFF eq "true") {
+ $diff .= "(In the diff below, changes in quantity "
+ . "of whitespace are not shown.)\n\n";
+ open(DIFF, "-|")
+ || exec "$cvsbin/cvs", '-Qn', 'diff', "$difftype",
+ '-b', "-r$prev_rev", "-r$rev", '--', $file;
+ }
+ }
+
+ if ($SEND_DIFF eq "true") {
+ while (<DIFF>) {
+ $diff .= $_;
+ }
+ close(DIFF);
+ }
+ $diff .= "\n\n";
+ }
+ }
+
+ &append_line($out, sprintf("%-9s%-12s%s%s", $rev, $delta,
+ $rcsfile, $diff));
+ }
+}
+
+
sub build_header {
local($header);
- local($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
- $header = sprintf("CVSROOT:\t%s\nModule name:\t%s\nRepository:\t%s\nChanges by:\t%s@%s\t%02d/%02d/%02d %02d:%02d:%02d",
- $cvsroot,
- $modulename,
- $dir,
- $login, $hostdomain,
- $year%100, $mon+1, $mday,
- $hour, $min, $sec);
+ delete $ENV{'TZ'};
+ local($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
+
+ $header = sprintf(" User: %-8s\n Date: %02d/%02d/%02d %02d:%02d:%02d",
+ $cvs_user, $year%100, $mon+1, $mday,
+ $hour, $min, $sec);
+# $header = sprintf("%-8s %02d/%02d/%02d %02d:%02d:%02d",
+# $login, $year%100, $mon+1, $mday,
+# $hour, $min, $sec);
+}
+
+# !!! Destination Mailing-list and history file mappings here !!!
+
+#sub mlist_map
+#{
+# local($path) = @_;
+# my $domain = "cvshome.org";
+#
+# if ($path =~ /^([^\/]+)/) {
+# return "cvs\@$1.$domain";
+# } else {
+# return "cvs\@$domain";
+# }
+#}
+
+sub derive_subject_from_changes_file ()
+{
+ my $subj = "";
+
+ for ($i = 0; ; $i++)
+ {
+ open (CH, "<$CHANGED_FILE.$i.$id.$cvs_user") or last;
+
+ while (my $change = <CH>)
+ {
+ # A changes file looks like this:
+ #
+ # src foo.c newfile.html
+ # www index.html project_nav.html
+ #
+ # Each line is " Dir File1 File2 ..."
+ # We only care about Dir, since the subject line should
+ # summarize.
+
+ $change =~ s/^[ \t]*//;
+ $change =~ /^([^ \t]+)[ \t]*/;
+ my $dir = $1;
+ # Fold to rightmost directory component
+ $dir =~ /([^\/]+)$/;
+ $dir = $1;
+ if ($subj eq "") {
+ $subj = $dir;
+ } else {
+ $subj .= ", $dir";
+ }
+ }
+ close (CH);
+ }
+
+ if ($subj ne "") {
+ $subj = "MODIFIED: $subj ...";
+ }
+ else {
+ # NPM: See if there's any file-addition notifications.
+ my $added = &read_line_nodie("$ADDED_FILE.$i.$id.$cvs_user");
+ if ($added ne "") {
+ $subj .= "ADDED: $added ";
+ }
+
+# print "derive_subject_from_changes_file().. added== $added \n";
+
+ ## NPM: See if there's any file-removal notications.
+ my $removed = &read_line_nodie("$REMOVED_FILE.$i.$id.$cvs_user");
+ if ($removed ne "") {
+ $subj .= "REMOVED: $removed ";
+ }
+
+# print "derive_subject_from_changes_file().. removed== $removed \n";
+
+ ## NPM: See if there's any branch notifications.
+ my $branched = &read_line_nodie("$BRANCH_FILE.$i.$id.$cvs_user");
+ if ($branched ne "") {
+ $subj .= "BRANCHED: $branched";
+ }
+
+# print "derive_subject_from_changes_file().. branched== $branched \n";
+
+ ## NPM: DEFAULT: DIRECTORY CREATION (c.f. "Check for a new directory first" in main mody)
+ if ($subj eq "") {
+ my $subject = join("/", @path);
+ $subj = "NEW: $subject";
+ }
+ }
+
+ return $subj;
}
-sub mail_notification {
- local(@text) = @_;
-
- # if only we had strftime()... stuff stolen from perl's ctime.pl:
- local($[) = 0;
-
- @DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
- @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
- 'Jul','Aug','Sep','Oct','Nov','Dec');
-
- # Determine what time zone is in effect.
- # Use GMT if TZ is defined as null, local time if TZ undefined.
- # There's no portable way to find the system default timezone.
- #
- $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : '';
-
- # Hack to deal with 'PST8PDT' format of TZ
- # Note that this can't deal with all the esoteric forms, but it
- # does recognize the most common: [:]STDoff[DST[off][,rule]]
- #
- if ($TZ =~ /^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/) {
- $TZ = $isdst ? $4 : $1;
- $tzoff = sprintf("%05d", -($2) * 100);
+sub mail_notification
+{
+ local($addr_list, @text) = @_;
+ local($mail_to);
+
+ my $subj = &derive_subject_from_changes_file ();
+
+ if ($EMULATE_LOCAL_MAIL_USER NE "") {
+ $MAIL_FROM = "$cvs_user\@$EMULATE_LOCAL_MAIL_USER";
}
- # perl-4.036 doesn't have the $zone or $gmtoff...
- ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $zone, $gmtoff) =
- ($TZ eq 'GMT') ? gmtime(time) : localtime(time);
+ $mail_to = join(", ", @{$addr_list});
- $year += ($year < 70) ? 2000 : 1900;
+ print "Mailing the commit message to $mail_to (from $MAIL_FROM)\n";
- if ($gmtoff != 0) {
- $tzoff = sprintf("%05d", ($gmtoff / 60) * 100);
- }
- if ($zone ne '') {
- $TZ = $zone;
- }
+ $ENV{'MAILUSER'} = $MAIL_FROM;
+ # Commented out on hocus, so comment it out here. -kff
+ # $ENV{'QMAILINJECT'} = 'f';
- # ok, let's try....
- $rfc822date = sprintf("%s, %2d %s %4d %2d:%02d:%02d %s (%s)",
- $DoW[$wday], $mday, $MoY[$mon], $year,
- $hour, $min, $sec, $tzoff, $TZ);
-
- open(MAIL, "| $MAILER");
- print MAIL "Date: " . $rfc822date . "\n";
- print MAIL "Subject: CVS Update: " . $modulename . "\n";
- print MAIL "To: " . $mailto . "\n";
- print MAIL "Reply-To: " . $replyto . "\n";
- print MAIL "\n";
- print MAIL join("\n", @text), "\n";
+ open(MAIL, "$MAIL_CMD -f$MAIL_FROM");
+ print MAIL "From: $MAIL_FROM\n";
+ print MAIL "To: $mail_to\n";
+ print MAIL "Subject: $SUBJECT_PRE $subj\n\n";
+ print(MAIL join("\n", @text));
close(MAIL);
+# print "Mailing the commit message to $MAIL_TO...\n";
+#
+# #added by jrobbins@collab.net 1999/12/15
+# # attempt to get rid of anonymous
+# $ENV{'MAILUSER'} = 'commitlogger';
+# $ENV{'QMAILINJECT'} = 'f';
+#
+# open(MAIL, "| /var/qmail/bin/qmail-inject");
+# print(MAIL "To: $MAIL_TO\n");
+# print(MAIL "Subject: cvs commit: $ARGV[0]\n");
+# print(MAIL join("\n", @text));
+# close(MAIL);
+}
+
+## process the command line arguments sent to this script
+## it returns an array of files, %s, sent from the loginfo
+## command
+sub process_argv
+{
+ local(@argv) = @_;
+ local(@files);
+ local($arg);
+ print "Processing log script arguments...\n";
+
+ while (@argv) {
+ $arg = shift @argv;
+
+ if ($arg eq '-u') {
+ $cvs_user = shift @argv;
+ } else {
+ ($donefiles) && die "Too many arguments!\n";
+ $donefiles = 1;
+ $ARGV[0] = $arg;
+ @files = split(' ', $arg);
+ }
+ }
+ return @files;
}
-sub write_commitlog {
- local($logfile, @text) = @_;
-
- open(FILE, ">>$logfile");
- print FILE join("\n", @text), "\n";
- close(FILE);
-}
+#############################################################
+#
+# Main Body
#
-# Main Body
+############################################################
#
+# Setup environment
+#
+umask (002);
+
+# Connect to the database
+$cvsbin = "/usr/bin";
+#
# Initialize basic variables
#
-$debug = 0;
-$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
+$id = getpgrp();
$state = $STATE_NONE;
-chop($hostname = `hostname`);
-chop($domainname = `domainname`);
-if ($domainname !~ '^\..*') {
- $domainname = '.' . $domainname;
-}
-$hostdomain = $hostname . $domainname;
-$cvsroot = $ENV{'CVSROOT'};
-$do_status = 1; # moderately useful
-$show_wd = 0; # useless in client/server
-$modulename = "";
-
-# parse command line arguments (file list is seen as one arg)
-#
-while (@ARGV) {
- $arg = shift @ARGV;
-
- if ($arg eq '-d') {
- $debug = 1;
- print STDERR "Debug turned on...\n";
- } elsif ($arg eq '-m') {
- if ($mailto eq '') {
- $mailto = shift @ARGV;
- } else {
- $mailto = $mailto . ", " . shift @ARGV;
- }
- } elsif ($arg eq '-R') {
- if ($replyto eq '') {
- $replyto = shift @ARGV;
- } else {
- $replyto = $replyto . ", " . shift @ARGV;
- }
- } elsif ($arg eq '-M') {
- $modulename = shift @ARGV;
- } elsif ($arg eq '-u') {
- $login = shift @ARGV;
- } elsif ($arg eq '-s') {
- $do_status = 0;
- } elsif ($arg eq '-w') {
- $show_wd = 1;
- } elsif ($arg eq '-f') {
- ($commitlog) && die("Too many '-f' args\n");
- $commitlog = shift @ARGV;
- } else {
- ($donefiles) && die("Too many arguments! Check usage.\n");
- $donefiles = 1;
- @files = split(/ /, $arg);
- }
-}
-if ($login eq '') {
- $login = getlogin || (getpwuid($<))[0] || "nobody";
-}
-($mailto) || die("No mail recipient specified (use -m)\n");
-if ($replyto eq '') {
- $replyto = $login;
-}
-
-# for now, the first "file" is the repository directory being committed,
-# relative to the $CVSROOT location
-#
+$cvs_user = $ENV{'USER'} || getlogin || (getpwuid($<))[0] || sprintf("uid#%d",$<);
+@files = process_argv(@ARGV);
@path = split('/', $files[0]);
-
-# XXX There are some ugly assumptions in here about module names and
-# XXX directories relative to the $CVSROOT location -- really should
-# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
-# XXX we have to parse it backwards.
-# XXX
-# XXX Fortunately it's relatively easy for the user to specify the
-# XXX module name as appropriate with a '-M' via the directory
-# XXX matching in loginfo.
-#
-if ($modulename eq "") {
- $modulename = $path[0]; # I.e. the module name == top-level dir
-}
+$repository = $path[0];
if ($#path == 0) {
$dir = ".";
} else {
- $dir = join('/', @path);
-}
-$dir = $dir . "/";
-
-if ($debug) {
- print STDERR "module - ", $modulename, "\n";
- print STDERR "dir - ", $dir, "\n";
- print STDERR "path - ", join(":", @path), "\n";
- print STDERR "files - ", join(":", @files), "\n";
- print STDERR "id - ", $id, "\n";
+ $dir = join('/', @path[1..$#path]);
}
+#print("ARGV - ", join(":", @ARGV), "\n");
+#print("files - ", join(":", @files), "\n");
+#print("path - ", join(":", @path), "\n");
+#print("dir - ", $dir, "\n");
+#print("id - ", $id, "\n");
-# Check for a new directory first. This appears with files set as follows:
#
-# files[0] - "path/name/newdir"
-# files[1] - "-"
-# files[2] - "New"
-# files[3] - "directory"
+# Map the repository directory to an email address for commitlogs to be sent
+# to.
#
-if ($files[2] =~ /New/ && $files[3] =~ /directory/) {
- local(@text);
+#$mlist = &mlist_map($files[0]);
- @text = ();
- push(@text, &build_header());
- push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification($mailto, @text);
-
- exit 0;
-}
-
-# Check for an import command. This appears with files set as follows:
+##########################
#
-# files[0] - "path/name"
-# files[1] - "-"
-# files[2] - "Imported"
-# files[3] - "sources"
+# Check for a new directory first. This will always appear as a
+# single item in the argument list, and an empty log message.
#
-if ($files[2] =~ /Imported/ && $files[3] =~ /sources/) {
- local(@text);
-
+if ($ARGV[0] =~ /New directory/) {
+ $header = &build_header;
@text = ();
- push(@text, &build_header());
+ push(@text, $header);
push(@text, "");
- push(@text, $files[0]);
- push(@text, "");
-
- while (<STDIN>) {
- chop; # Drop the newline
- push(@text, $_);
- }
-
- &mail_notification(@text);
-
+ push(@text, " ".$ARGV[0]);
+ &mail_notification([ $mlist ], @text);
exit 0;
}
+#
# Iterate over the body of the message collecting information.
#
while (<STDIN>) {
- chop; # Drop the newline
-
- if (/^In directory/) {
- if ($show_wd) { # useless in client/server mode
- push(@log_lines, $_);
- push(@log_lines, "");
- }
- next;
+ chomp; # Drop the newline
+ if (/^Revision\/Branch:/) {
+ s,^Revision/Branch:,,;
+ push (@branch_lines, split);
+ next;
}
-
+# next if (/^[ \t]+Tag:/ && $state != $STATE_LOG);
if (/^Modified Files/) { $state = $STATE_CHANGED; next; }
if (/^Added Files/) { $state = $STATE_ADDED; next; }
if (/^Removed Files/) { $state = $STATE_REMOVED; next; }
if (/^Log Message/) { $state = $STATE_LOG; next; }
-
- s/^[ \t\n]+//; # delete leading whitespace
- s/[ \t\n]+$//; # delete trailing whitespace
+ s/[ \t\n]+$//; # delete trailing space
- if ($state == $STATE_CHANGED) { push(@changed_files, split); }
- if ($state == $STATE_ADDED) { push(@added_files, split); }
- if ($state == $STATE_REMOVED) { push(@removed_files, split); }
- if ($state == $STATE_LOG) { push(@log_lines, $_); }
+ push (@changed_files, split) if ($state == $STATE_CHANGED);
+ push (@added_files, split) if ($state == $STATE_ADDED);
+ push (@removed_files, split) if ($state == $STATE_REMOVED);
+ if ($state == $STATE_LOG) {
+ if (/^PR:$/i ||
+ /^Reviewed by:$/i ||
+ /^Submitted by:$/i ||
+ /^Obtained from:$/i) {
+ next;
+ }
+ push (@log_lines, $_);
+ }
}
+#
# Strip leading and trailing blank lines from the log message. Also
# compress multiple blank lines in the body of the message down to a
# single blank line.
+# (Note, this only does the mail and changes log, not the rcs log).
#
while ($#log_lines > -1) {
last if ($log_lines[0] ne "");
@@ -433,144 +616,105 @@ while ($#log_lines > -1) {
}
for ($i = $#log_lines; $i > 0; $i--) {
if (($log_lines[$i - 1] eq "") && ($log_lines[$i] eq "")) {
- splice(@log_lines, $i, 1);
+ splice(@log_lines, $i, 1);
}
}
-if ($debug) {
- print STDERR "Searching for log file index...";
-}
-# Find an index to a log file that matches this log message
+#
+# Find the log file that matches this log message
#
for ($i = 0; ; $i++) {
- local(@text);
-
- last if (! -e "$LOG_FILE.$i.$id"); # the next available one
- @text = &read_logfile("$LOG_FILE.$i.$id", "");
- last if ($#text == -1); # nothing in this file, use it
- last if (join(" ", @log_lines) eq join(" ", @text)); # it's the same log message as another
-}
-if ($debug) {
- print STDERR " found log file at $i.$id, now writing tmp files.\n";
+ last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
+ @text = &read_logfile("$LOG_FILE.$i.$id.$cvs_user", "");
+ last if ($#text == -1);
+ last if (join(" ", @log_lines) eq join(" ", @text));
}
+#
# Spit out the information gathered in this pass.
#
-&append_names_to_file("$CHANGED_FILE.$i.$id", $dir, @changed_files);
-&append_names_to_file("$ADDED_FILE.$i.$id", $dir, @added_files);
-&append_names_to_file("$REMOVED_FILE.$i.$id", $dir, @removed_files);
-&write_logfile("$LOG_FILE.$i.$id", @log_lines);
+&write_logfile("$LOG_FILE.$i.$id.$cvs_user", @log_lines);
+&append_to_file("$BRANCH_FILE.$i.$id.$cvs_user", $dir, @branch_lines);
+&append_to_file("$ADDED_FILE.$i.$id.$cvs_user", $dir, @added_files);
+&append_to_file("$CHANGED_FILE.$i.$id.$cvs_user", $dir, @changed_files);
+&append_to_file("$REMOVED_FILE.$i.$id.$cvs_user", $dir, @removed_files);
+&append_line("$MLIST_FILE.$i.$id.$cvs_user", $mlist);
+if ($rcsidinfo) {
+ &change_summary("$SUMMARY_FILE.$i.$id.$cvs_user", (@changed_files, @added_files));
+}
+#
# Check whether this is the last directory. If not, quit.
#
-if ($debug) {
- print STDERR "Checking current dir against last dir.\n";
+if (-e "$LAST_FILE.$id.$cvs_user") {
+ $_ = &read_line("$LAST_FILE.$id.$cvs_user");
+ $tmpfiles = $files[0];
+ $tmpfiles =~ s,([^a-zA-Z0-9_/]),\\$1,g;
+ if (! grep(/$tmpfiles$/, $_)) {
+ print "More commits to come...\n";
+ exit 0
+ }
}
-$_ = &read_line("$LAST_FILE.$id");
-if ($_ ne $cvsroot . "/" . $files[0]) {
- if ($debug) {
- print STDERR sprintf("Current directory %s is not last directory %s.\n", $cvsroot . "/" .$files[0], $_);
- }
- exit 0;
-}
-if ($debug) {
- print STDERR sprintf("Current directory %s is last directory %s -- all commits done.\n", $files[0], $_);
-}
-
-#
-# End Of Commits!
#
-
# This is it. The commits are all finished. Lump everything together
# into a single message, fire a copy off to the mailing list, and drop
# it on the end of the Changes file.
#
+$header = &build_header;
#
# Produce the final compilation of the log messages
#
@text = ();
-@status_txt = ();
-push(@text, &build_header());
+@mlist_list = ();
+push(@text, $header);
push(@text, "");
-
for ($i = 0; ; $i++) {
- last if (! -e "$LOG_FILE.$i.$id"); # we're done them all!
- @lines = &read_logfile("$CHANGED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Modified files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$ADDED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Added files:");
- push(@text, &format_lists(@lines));
- }
- @lines = &read_logfile("$REMOVED_FILE.$i.$id", "");
- if ($#lines >= 0) {
- push(@text, "Removed files:");
- push(@text, &format_lists(@lines));
- }
- if ($#text >= 0) {
- push(@text, "");
- }
- @lines = &read_logfile("$LOG_FILE.$i.$id", "\t");
- if ($#lines >= 0) {
- push(@text, "Log message:");
- push(@text, @lines);
- push(@text, "");
- }
- if ($do_status) {
- local(@changed_files);
-
- @changed_files = ();
- push(@changed_files, &read_logfile("$CHANGED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$ADDED_FILE.$i.$id", ""));
- push(@changed_files, &read_logfile("$REMOVED_FILE.$i.$id", ""));
-
- if ($debug) {
- print STDERR "main: pre-sort changed_files = ", join(":", @changed_files), ".\n";
- }
- sort(@changed_files);
- if ($debug) {
- print STDERR "main: post-sort changed_files = ", join(":", @changed_files), ".\n";
- }
-
- foreach $dofile (@changed_files) {
- if ($dofile =~ /\/$/) {
- next; # ignore the silly "dir" entries
- }
- if ($debug) {
- print STDERR "main(): doing 'cvs -nQq status -v $dofile'\n";
- }
- open(STATUS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $dofile;
- while (<STATUS>) {
- chop;
- push(@status_txt, $_);
- }
- }
+ last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
+ push(@text, &read_file("$BRANCH_FILE.$i.$id.$cvs_user", "Branch:"));
+ push(@text, &read_file("$CHANGED_FILE.$i.$id.$cvs_user", "Modified:"));
+ push(@text, &read_file("$ADDED_FILE.$i.$id.$cvs_user", "Added:"));
+ push(@text, &read_file("$REMOVED_FILE.$i.$id.$cvs_user", "Removed:"));
+ push(@text, " Log:");
+ push(@text, &read_logfile("$LOG_FILE.$i.$id.$cvs_user", " "));
+ push(@mlist_list, &read_file_lines("$MLIST_FILE.$i.$id.$cvs_user"));
+ if ($rcsidinfo == 2) {
+ if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") {
+ push(@text, " ");
+ push(@text, " Revision Changes Path");
+ push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", " "));
+ }
}
+ push(@text, "");
}
-# Write to the commitlog file
#
-if ($commitlog) {
- &write_commitlog($commitlog, @text);
+# Now generate the extra info for the mail message..
+#
+if ($rcsidinfo == 1) {
+ $revhdr = 0;
+ for ($i = 0; ; $i++) {
+ last if (! -e "$LOG_FILE.$i.$id.$cvs_user");
+ if (-e "$SUMMARY_FILE.$i.$id.$cvs_user") {
+ if (!$revhdr++) {
+ push(@text, "Revision Changes Path");
+ }
+ push(@text, &read_logfile("$SUMMARY_FILE.$i.$id.$cvs_user", ""));
+ }
+ }
+ if ($revhdr) {
+ push(@text, ""); # consistancy...
+ }
}
-if ($#status_txt >= 0) {
- push(@text, @status_txt);
-}
+%mlist_hash = ();
-# Mailout the notification.
-#
-&mail_notification(@text);
+foreach (@mlist_list) { $mlist_hash{ $_ } = 1; }
-# cleanup
#
-if (! $debug) {
- &cleanup_tmpfiles();
-}
-
+# Mail out the notification.
+#
+&mail_notification([ keys(%mlist_hash) ], @text);
+&cleanup_tmpfiles;
exit 0;
OpenPOWER on IntegriCloud