#你可以输出结果在Excel中打开进行分组统计(按日期、用户,稍稍加工后还可以按模块)
#
# Get ClearCase history data.
#Author:wenfangl
#Mail:wenfangl@gmail.com
#用法 D:\AE>perl D:\AE\change.pl view=M:\wenfangl_view\Project out=d:\ae\200704.csv since=2007-03-01 debug=1
#注意:只能对动态视图起作用
# 参数:
# view=<path> 视图路径
# out=<path> 输出文件路径及名称
# since=<startdate> 开始日期
# debug=1 是否显示输出信息在窗口
$| = 1;
$logs_dir = "
D:\\AE";
#输出日志目录
$vob_logs = "vobs";
&
parse_arguments(@ARGV);
#解析命令行得到相关变量
#以下是判断相关变量是否可用的
if (!(defined $view)) {
die "view directory must be defined";
}
if (!(defined $data_file)) {
die "output file must be defined";
}
if($debug == 1) {
print "View is $view \n";
print "Output file is $data_file \n";
print "Starting point is $startdate \n";
}
open(DATAFILE, ">".$data_file) || die "Unable to open '$data_file' for writing.\n";
chdir $logs_dir || die "Unable to open log directory ,$logs_dir";
unless (opendir(DIR, $vob_logs)) {
mkdir($vob_logs);
opendir(DIR, $vob_logs) || die "Unable to open vob log directory";
}
close (DIR);
chdir $vob_logs;
unless (opendir(DIR, $view)) {
die "Can not open view directory";
}
#执行解析目录的函数
while ($file = readdir(DIR)) {
next if ($file =~ /^\.+$/);
&
get_data("$view\\$file");
}
close (DIR);
close (DATAFILE);
#获取VOB名称
sub
get_vob_name
{
my ($item) = $_[0];
my $cmd = "cleartool describe vob:$item 2>nul";
if($debug == 1)
{
print $cmd, "\n";
}
open(CT, "$cmd|") or die("$cmd failed: $!\n");
while(<CT>)
{
chomp($_);
my (@pieces) = split(/\n'/, $_);
foreach $piece(@pieces)
{
if(grep(/versioned object base/, $piece))
{
$vobname = substr($piece, index($piece, "\"") + 2, length($piece) - index($piece, "\"") - 3); }
break;
}
}
if($debug == 1)
{
print "Vob is $vobname\n";
}
close (CT);
}
#获取历史数据
sub
get_data
{
my ($item) = $_[0];
if($debug == 1)
{
print "Getting history for $item\n";
}
&
get_vob_name($item);
undef $since;
if(!(defined $startdate))
{
if(open(COLLECTION_FILE, $vobname))
{
$last_collect_time = <COLLECTION_FILE>;
close COLLECTION_FILE;
chomp($last_collect_time);
if($last_collect_time ne "")
{
if($debug == 1)
{
print "Last collection time is $last_collect_time\n";
}
$since = "-since $last_collect_time";
}
}
}
else
{
$since = $startdate;
}
#Record the time of this collection
@months = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
($seconds, $minutes, $hour, $monthDate, $month, $year, $weekday, $yeardate, $dls) = localtime(time);
$year += 1900;
$collection_time = "$monthDate-@months[$month]-$year.$hour:$minutes:$seconds";
#收集历史数据,详见cleartool man lshistory
my $cmd = "cleartool lshistory -recurse -fmt \"%Nd,,%u,,%o,,%m,,%En,,%Sn\\n\" $since $item 2>nul";
if($debug == 1)
{
print "Executing $cmd \n";
}
open(CT, "$cmd|") or die("$cmd failed: $!\n");
while(<CT>)
{
chomp($_);
# ignore the lost+found directory.
next if(m![/\\]lost\+found[/\\]!);
if($debug == 1)
{
print $_, "\n" ;
}
#以下是过滤获取的历史数据
my($date, $user, $op, $kind, $path, $version,$Comment) = split(/,,/, $_);
my($day, $time) = split(/\./, $date);
next if($op eq '
checkout');
next if($op eq 'unlock');
next if($op eq 'lock');
next if($op eq 'mkbranch' && $kind eq 'branch');
next if($op eq 'mkbranch' && $kind eq 'directory version');
next if($op eq 'rmver' && $kind eq 'branch');
next if($op eq 'mkbranch' && $kind eq 'version');
next if($op eq 'mkelem' && $kind eq 'branch');
next if($op eq 'mkelem' && $kind eq 'version');
next if($op eq 'mkelem' && $kind eq 'file element');
next if($op eq 'mkelem' && $kind eq 'directory element');
next if($op eq 'mkelem' && $kind eq 'directory version');
next if($op eq 'checkin' && $kind eq 'directory version');
next if(grep(/null operation kind/, $op)); #bug in ClearCase
my $index = rindex($version, "\\");
my $branch = substr($version, 0, $index);
my $objectversion = substr($version, $index + 1);
#Format the date in the SQL date format
my $year = substr($day, 0, 4);
my $month = substr($day, 4, 2);
$day = substr($day, 6);
$date = "$year-$month-$day";
my($delta1, $delta2, $added, $deleted);
if($op eq 'checkin' && $kind eq 'version')
{
($delta1, $delta2, $added, $deleted) =
diff2delta($path, $version);
if($delta2 > $delta1)
{
$added += $delta2 - $delta1;
}
elsif($delta1 > $delta2)
{
$deleted += $delta1 - $delta2;
}
}
#输出数据格式:时间,用户名,操作,操作类型,路径,分支,版本,修改行数,添加行数,删除行数
$outputdata = "$date\t$user\t$op\t$kind\t$path\t$branch\t$objectversion\t$delta1\t$added\t$deleted\t";
if($debug == 1)
{
print "Writing to the output file: $outputdata \n" ;
}
print DATAFILE "$outputdata\n";
}
close(CT);
#Record the time of this collection
open(COLLECTION_FILE, ">$vobname");
print COLLECTION_FILE "$collection_time\n";
close COLLECTION_FILE;
}
#解析文件变化数据
sub
diff2delta
{
my $delta1 = 0;
my $delta2 = 0;
my $added = 0;
my $deleted = 0;
my($path, $version) = @_;
#ClearCase不能解析doc文档,过滤他们
my $filename = substr($path, rindex($path, "\\") + 1);
my ($extension) = substr($filename, rindex($filename, ".") + 1);
if($extension eq "doc")
{
return;
}
my $cmd = qq(cleartool diff -diff_format -pred "$path\@\@$version" 2>nul);
open(DIFF, "$cmd|") or die("$cmd failed: $!\n");
local($_);
while(<DIFF>)
{
if(/^\d+a\d+$/)
{
$added++;
}
elsif(/^\d+a(\d+),(\d+)$/)
{
$added += $2 - $1;
}
elsif(/^\d+d\d+$/)
{
$deleted++;
}
elsif(/^(\d+),(\d+)d\d+$/)
{
$deleted += $2 - $1 + 1;
}
elsif(/^\d+c\d+$/)
{
$delta1++;
$delta2++;
}
elsif(/^(\d+),(\d+)c(\d+),(\d+)$/)
{
$delta1 += $2 - $1 + 1;
$delta2 += $4 - $3 + 1;
}
}
close(DIFF);
($delta1, $delta2, $added, $deleted);
}
#解析命令行参数
sub
parse_arguments{
foreach $p (@_)
{
print $p;
print "\n";
if (!($p =~ /=/))
{
warn "Illegal parameter $p. Skipping.";
next;
}
local($param, $value) = split(/=/, $p, 2);
#print $param;
if ($param eq "out")
{
$data_file=$value;
next;
}
if ($param eq "view")
{
$view=$value;
next;
}
if ($param eq "since")
{
$startdate="-since $value";
next ;
}
if ($param eq "debug")
{
$debug = $value;
next ;
}
}
}
1;
[
本帖最后由 skylwf 于 2007-9-10 16:40 编辑 ]