[cvsnt] email notification help - script attached

Chris Purves pchris at aims-bio.com
Thu Jul 19 17:04:31 BST 2007

On Wed, 11 Jul 2007 09:16:02 -0600, Glen Starrett  
<glen.starrett at march-hare.com> wrote:

> Chris Purves wrote:
>> I would prefer
>> to have one e-mail represent all changes made to a module in a single  
>> day.
> Try this:
> 	cvs -d CVSROOT rlog -d "yesterday<now" MODULE
> See if that produces the list you'd like to see.

Yes, that command was very helpful.  I have incorporated it into the  
script below which checks for changes that occured yesterday and sends a  
message to all members of a corresponding group for module.  The script  
also assumes that a user's e-mail address is stored in the passwd file,  
which will not be the case for most users, but is for me since I am  
managing my passwd file with another program, TWiki.  So, for most the  
script below would need to be modifed to pull e-mails from a different  

Please feel free to make use of the following script.


# This script generates a list of changes to a CVS repository
# on a module by modules bassis for all changes made yesterday.
# For each module with commits made an e-mail is sent to each
# member in a group.
# This script requires that sendmail is an executable
# This script expects that the passwd file be of the form
# username:password hash:e-mail address
# This is because my CVSNT setup uses the .htpasswd file created
# by TWiki which includes e-mail addresses.  This is not the
# standard passwd configuration for CVS which has the system
# user at the end.  For standard CVS setups, this script will
# need to be modified to use another method to match users
# to e-mail addresses.
# This script orignally written by Chris Purves

## User modifiable section

# Set locations for directores.  The script will create a subdirectory
# inside the temporary directory and remove the subdirectory
# when finished.  The location of the cvs repository on the
# filesystem must be entered.

# list of modules seperated by spaces
modules="product_docs test"
# list of groups corresponding to modules seperated by spaces
groups="CVSProductDocsGroup CVSTestGroup"

## Main section of script.  Do not modify.

# Check if temp directory exists.  If it does stop the script.
# We don't want to recursively delete an existing directory.
# If all is good, create cvsmailer directory.
if [ -d $tmpdir/cvsmailer ]
   echo "Directory $tmpdir/cvsmailer exists."
   echo "Program exiting."
   mkdir $tmpdir/cvsmailer

# generate begin and end dates for yesterday to be used with
# cvs rlog command
yesterday=`date -d "yesterday" +%Y-%m-%d`
begin="$yesterday 00:00"
end="$yesterday 23:59"

# Convert groups variable into group array.  This may not
# be the most elegant method, but it's what I could think
# of.
for item in $groups
   let "i+=1"

# main loop
# cycle through modules
for module in $modules
   # use cvs rlog command and write output to a file.  Send errors
   # to /dev/null
   cvs -d :local:$cvsdir rlog -d "$begin"\<"$end" $module >  
$tmpdir/cvsmailer/$module 2> /dev/null
   # We only want to continue with this module if there were revisions
   # made, so we check.
   if grep -q "selected revisions: 0" $tmpdir/cvsmailer/$module
     # We're really only interested in the false case, but we still
     # need to do something for the true case...maybe not the best way
     echo "true" > /dev/null
     # Okay, we have revisions!
     # I don't like the rlog header, so remove it.
     # I want to use $cvsdir with sed, but the /'s cause problems, so  
change them to \\/'s
     sedcvsdir=`echo $cvsdir | sed 's/\//\\\\\//g'`
     while read line
       # Replace RCS file... with filename as header for section
       if echo $line | grep -q "^RCS file:"
         echo $line | sed "s/RCS file:  
$sedcvsdir\/$module\/\(.*\),v/********** \1 **********/" >>  
       # Only write lines where trigger = 1
       if [ $trigger -eq 1 ]
         echo "$line" >> $tmpdir/cvsmailer/tempfile
       # The line beginning "description" marks the end of the log header
       # Once we see that we can set trigger to 1
       if [ "$line" = "description:" ]
       # The line beginning "=====" marks the end of a section.  Reset
       # trigger to 0 so that next header is not written to output.
       if echo $line | grep -q ======
     done < $tmpdir/cvsmailer/$module
     mv $tmpdir/cvsmailer/tempfile $tmpdir/cvsmailer/$module
     # Pull users from the group that corresponds to this module.
     names=`grep "${group[$i]}" $cvsdir/CVSROOT/group | sed 's/^.*: //'`
     # For each user, find their e-mail address from the passwd file
     # and store in a variable $address
     for name in $names
       email=`grep $name $cvsdir/CVSROOT/passwd | sed 's/.*://'`
       address="$address, $email"
     address=`echo $address | sed 's/^, //'`
     # Create an e-mail template and append the log
     # The first line overwrites the file in case there are more than
     # one module with changes.  After that append.
     echo "From: \"CVS Mailer\" <pchris at aims-bio.com>" >  
     echo "To: $address" >> $tmpdir/cvsmailer/cvsmail
     echo "Subject: CVS Commit to $module" >> $tmpdir/cvsmailer/cvsmail
     echo "" >> $tmpdir/cvsmailer/cvsmail
     echo "The following changes have been made to the $module module." >>  
     echo "" >> $tmpdir/cvsmailer/cvsmail
     cat $tmpdir/cvsmailer/$module >> $tmpdir/cvsmailer/cvsmail
     # Use sendmail command to send the e-mail.
     sendmail -t < $tmpdir/cvsmailer/cvsmail
   # Increment to correctly index the group array.
   let "i+=1"

# Remove the created directory inside the tmpdir.  Since we checked
# that this directory did not exist at the start, it should be safe.
rm -r $tmpdir/cvsmailer

Chris Purves

More information about the cvsnt mailing list