/home/cvsroot/test/CVSROOT/loginfo 文件用于控制仓库中版本变更和目录添加之后,log 信息发送到哪里的控制。 loginfo相当于是一个事件驱动器,只要提交了新的版本到cvs中就会触发里面的程序。

loginfo 文件有一个标准的脚本 hook 形式(参阅 Trigger Scripts),每一行是一个正则表达式和所执行的命令。它支持 ALL 和 DEFAULT 关键字。

调用任何指定的脚本:

commit
每个目录一次,在此目录中的所有文件成功提交之后立即执行。

import
每个 import 一次,完成所有写操作之后立即执行。

add
成功 add 到目录之后立即执行。
通过 loginfo 调用的任何脚本会从标准输入获得 log 信息。注意过滤程序 必须 从标准输入读 所有 的 log 信息,否则 cvs 将因管道信号打断而失败。

除了通用格式化字符串以外(参阅 syntax),loginfo 还支持:

{stVv}
文件属性,其中:
s    文件名

T    目标的标签名,或者在没有相关标签的时候为空字串(通常是主干)

V    旧版本号(提交前)

v    新版本号(提交后)
例如,有效的格式化字符串是 `%%', `%s', `%{s}' 和 `%{stVv}'。

我们了解了loginfo的功能以后就知道我要做什么,我们将提交到cvs里面的版本能不能直接发行,这样岂不是很方便。下面这个程序就解决了这样的问题。原来程序只是作为版本修改通知,现在我改进以后同时支持发布了。

#! /usr/bin/perl
-*-Perl-*-
#

# Usage:  
log.pl [-u user] [[-m mailto] ] [-s] [-V] -'execution dir' -f logfile 'dirname file '
#
#       
-u user         - $USER passed from loginfo
#       
-m mailto       - for each user to receive cvs log reports
#                       (multiple 
-m's permitted)
#       -s              - to prevent "cvs status -v" messages
#       
-V              - without '-s', don't pass '-v' to cvs status
#       -a dirname      - to specify actual execution directory
#       
-f logfile      - for the logfile to append to (mandatory,
#                       but only one logfile can be specified).


use strict;
use IO::File;

my $cvsroot 
= $ENV{'CVSROOT'};

# turn off setgid
#
$) 
= $(;

my $dostatus 
= 1;
my $verbosestatus 
= 1;
my $users;
my $login;
my $donefiles;
my $logfile;
my $activedir;
my @files;

# parse command line arguments
#
while (@ARGV) {
        my $arg 
= shift @ARGV;

        
if ($arg eq '-m') {
                $users = "$users " . shift @ARGV;
        } elsif ($arg eq 
'-u') {
                $login = shift @ARGV;
        } elsif ($arg eq 
'-f') {
                ($logfile) && die "Too many '-f' args";
                $logfile 
= shift @ARGV;
        } elsif ($arg eq 
'-a') {
                $activedir = shift @ARGV;
        } elsif ($arg eq 
'-s') {
                $dostatus = 0;
        } elsif ($arg eq 
'-V') {
                $verbosestatus = 0;
        } 
else {
                ($donefiles) 
&& die "Too many arguments!\n";
                $donefiles 
= 1;
                @files 
= split(/ /, $arg);
        }
}

# the first argument 
is the module location relative to $CVSROOT
#
my $modulepath 
= shift @files;
my $mailcmd 
= "| Mail -s 'CVS update: $modulepath'";

# Initialise some 
date and time arrays
#
my @mos 
= ('January','February','March','April','May','June','July',
        'August','September','October','November','December');
my @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');

my ($sec,$min,$
hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
$
year += 1900;

get a login name for the guy doing the commit.
#
if ($login eq '') {
        $login = getlogin || (getpwuid($<))[0] || "nobody";
}

# open 
log file for appending
#
my $logfh 
= new IO::File ">>" . $logfile
        
or die "Could not open(" . $logfile . "): $!\n";

# send mail, 
if there's anyone to send to!
#
my $mailfh;
if ($users) {
        $mailcmd 
= "$mailcmd $users";
        $mailfh 
= new IO::File $mailcmd
                
or die "Could not Exec($mailcmd): $!\n";
}

# print out the 
log Header
#
$logfh
->print ("\n");
$logfh
->print ("****************************************\n");
$logfh
->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n");
$logfh
->print ("Author:\t$login\n\n");

if ($mailfh) {
        $mailfh
->print ("\n");
        $mailfh
->print ("Date:\t$days[$wday] $mos[$mon] $mday, $year @ $hour:" . sprintf("%02d", $min) . "\n");
        $mailfh
->print ("Author:\t$login\n\n");
}

# print the stuff from logmsg that comes in 
on stdin to the logfile
#
my $infh 
= new IO::File "< -";

my $cno 
= 0;
my $cdir;
foreach ($infh
->getlines) {
        $logfh
->print;
        #print(
"cc-> $_");
        
if($cno == 1){
          my $ff 
= $_;
          my @nw 
= split (/:/, $ff) ;
          $cdir 
= @nw[1];
        }
        
if ($mailfh) {
                $mailfh
->print ("$_");
        }
        $cno
++;
}
undef $infh;

$logfh
->print ("\n");
#print(
"cdir=$cdir");
my $adir 
= substr $cdir, 0, length($cdir) - 1;
#my $asubdir 
= substr $cdir, 18 ;
my $asubdir 
= substr ($cdir, index($cdir,"/",5+ 1) ;
chomp $asubdir;
my $ain 
= index($modulepath,"/");
my $mopath_sub 
= substr ($modulepath, $ain+1);

# after 
log information, do an 'cvs -Qq status -v' on each file in the arguments.
#
if ($dostatus != 0) {
        
while (@files) {
                my $file 
= shift @files;

                
if ($file eq "-") {
                        $logfh
->print ("[input file was '-']\n");
                        
if ($mailfh) {
                                $mailfh
->print ("[input file was '-']\n");
                        }

                        exec 
"mkdir -m 755 $activedir/$mopath_sub";
                        #die 
"file transfer for latest version failed: $!";
                        last;
                }
                my $rcsfh 
= new IO::File;
                my $pid 
= $rcsfh->open ("-|");
                
if ( !defined $pid )
                {
                        die 
"fork failed: $!";
                }
                
if ($pid == 0)
                {
                        my @command 
= ('cvs', '-nQq', 'status');
                        if ($verbosestatus)
                        {
                                push @command, 
'-v';
                        }
                        push @command, $file;
                        exec @command;
                        die 
"cvs exec failed: $!";

                } 

                my $line;
                
while ($line = $rcsfh->getline) {
                        $logfh
->print ($line);
                        
if ($mailfh) {
                                $mailfh
->print ($line);
                        }
                }

                #print(
"cp $adir/$file $activedir/$mopath_sub,$asubdir \n");
                print (
"\n  Active Dir : $activedir/$asubdir  \n");
                
if(index($asubdir,"src/")==0){
                  my $tmp_2
=substr $asubdir,4;
                  $asubdir 
= "WebRoot/WEB-INF/classes/$tmp_2";
                  
if(-"$activedir/$asubdir"){
                    print(
"Dir exists:$activedir/$asubdir \n");
                  }
else{
                    exec 
"mkdir -p $activedir/$asubdir";
                  }
                }
                print(
"cp $adir/$file $activedir/$asubdir \n");
        
if(index($asubdir,"/tmp/cvs-")==0){
            exec 
"cp $adir/$file $activedir";
        }
else{
            exec 
"cp $adir/$file $activedir/$asubdir";
        }
        
                #die 
"file transfer for latest version failed: $!";

                undef $rcsfh;
        }
}

$logfh
->close()
        
or die "Write to $logfile failed: $!";

if ($mailfh)
{
        $mailfh
->close;
        die 
"Pipe to $mailcmd failed" if $?;
}
## must 
exit cleanly
##
exit 0;