Category: Utility Script
Author/Contact Info grahame@regress.homelinux.org
Description: This script cvs updates a list of projects and emails a report of files affected to the user.

A file called .cvsupdaterc is required and has to be in the following format :

sendreportto@somedomain.org
reportsentby@anotherdomain.org
/home/someuser/project1
/home/someuser/project2
...
/home/someuser/someother/project
#!/usr/bin/perl -w

# This script is supposed to read a list of projects in from
# ~/.cvsupdaterc the projects are listed one per line except
# on the first two lines which are reserved for the
# 'send to' and 'sent by' email addresses. Once the
# project list has been read in they are updated to the
# latest code from the main cvs repository. A temporary log
# of the files affected is created and emailed to you for
# each project.

# please send any comments, patches, etc to me at :
# grahame@notofthisearth.freeserve.co.uk

# Please note you use this script at your own risk. I cannot
# and will not take responsibilty for anything that may, or
# may not happen.
# Furthermore this script was not designed with either
# security or portability in mind. If you wish to submit a
# patch feel free to do so, I'll certainly take a look, and
# I may even apply it, giving credit where it is due
# obviously.

use warnings;
use strict;
use File::Basename qw/ basename /;
use Mail::Mailer;

$^L = "\n"; # Replace formfeed with newline

chdir;

my $file = "";
my $configfile = ".cvsupdaterc";
my $cvstmpdir = ".cvsupdate";
my $command = "cvs update -dCR > ~/.cvsupdate/";

die "No '$configfile' file available, exiting.\n"
    if !(-e $configfile); # Check if config file exists

if (!(-d $cvstmpdir))
{
    print "$cvstmpdir doesn't exist, creating ... \n";
    mkdir $cvstmpdir, 0755 or
        die "Cannot create $cvstmpdir, exiting\n";
}

open CONFIG, $configfile;
chomp (my @projects = <CONFIG>);
close CONFIG;

my $emailto = shift @projects;
my $emailfrom = shift @projects;

# Enter the root directory for each project and update the
# project if it exists
foreach $line (@projects)
{
    my @patched =();
    my @updated =();
    my @conflict =();
    my @modified =();
    
    my $project = basename $line;
    my $projectlog = $cvstmpdir."/".$project;
    
    print "\nUpdating ... ".$project."\n";
    if (-d $line)
    {
        chdir $line;
        # eww, must find better way of doing this
        system($command.$project);
    }
    else
    {
        print "Cannot find $line, skipping\n";
    }
    
    chdir;
    open LOG, $projectlog;
    
    foreach my $entry (<LOG>)
    {
        push @patched, $entry
            if substr($entry, 0, 1) eq "P";
        push @updated, $entry
            if substr($entry, 0, 1) eq "U";
        push @conflict, $entry
            if substr($entry, 0, 1) eq "C";
        push @modified, $entry
            if substr($entry, 0, 1) eq "M";
    }
    close LOG;
    
    open REPORT, ">$projectlog";
    select REPORT;

    $= = 0;
    
    if (@patched > 0)
    {
        $= = scalar @patched + 2;
        $~ = "REPORT_PATCHED";
        $^ = "REPORT_PATCHED_TOP";
        foreach $file (@patched)
        {
            write();
        }
        print "\n";
    }

    if (@updated > 0)
    {
        $= = scalar @updated + 2;
        $~ = "REPORT_UPDATED";
        $^ = "REPORT_UPDATED_TOP";
        foreach $file (@updated)
        {
            write();
        }
        print "\n";
    }                                                                 
+               

    if (@conflict > 0)
    {
        $= = scalar @conflict + 2;
        $~ = "REPORT_CONFLICT";
        $^ = "REPORT_CONFLICT_TOP";
        foreach $file (@conflict)
        {
            write();
        }
        print "\n";
    }
                                                                      
+      
    if (@modified > 0)
    {
        $= = scalar @modified + 2;
        $~ = "REPORT_MODIFIED";
        $^ = "REPORT_MODIFIED_TOP";
        foreach $file (@modified)
        {
            write();
        }
        print "\n";
    }
    close REPORT;
    select STDOUT;

    
    if (!(-z $projectlog))
    {

        open TEXTBODY, $projectlog;

        my @body = <TEXTBODY>;

        my $mailprog = new Mail::Mailer;
            
        my %headers = (
        'To' => $emailto,
        'From' => $emailfrom,
        'Subject' => $project
        );
        
        $mailprog->open (\%headers);
        print $mailprog @body;
        $mailprog->close;
        
        close TEXTBODY;
    }
    unlink $projectlog;
}

format REPORT_PATCHED_TOP =
Patched files
-------------
.

format REPORT_PATCHED =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$file
.

format REPORT_UPDATED_TOP =
Updated files
-------------
.

format REPORT_UPDATED =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$file
.

format REPORT_CONFLICT_TOP =
Conflicting files
-----------------
.
format REPORT_CONFLICT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$file
.

format REPORT_MODIFIED_TOP =
Modified files
--------------
.

format REPORT_MODIFIED =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$file
.