/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] -a '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(-d "$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;