解析SVN日志中的更改路径以获取包名
我在Linux上运行以下命令,以生成某个版本的详细日志。
svn log -v -r12345 http://svn-remote.com/path
输出结果是:
------------------------------------------------------------------------
r12345 | debajyoti.das@email.com | 2013-02-07 01:27:08 -0800 (Thu, 07 Feb 2013) | 1 line
Changed paths:
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/Main.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleGroupTask.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleProcessTaskBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleSequenceProcessTaskBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.test/src/main/java/com/companyname/cycle/test/bll/MockCycleBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/pas.cycle/src/main/java/com/companyname/pas/cycle/bll/DasCycleBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/pas.cycle/src/main/java/com/companyname/pas/cycle/dal/DasCycleDal.java
BUG ID 12345678 - BLAH IMPLEMENTATION IN PROJECT.CYCLE
------------------------------------------------------------------------
我想从这个日志中提取出每个文件的包名。比如:
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleGroupTask.java
我该如何写一个perl、python或者shell脚本来实现这个功能,这样使用起来就像这样,例如:
$ perl svnlog.pl 12345 > log.txt
2 个回答
1
我觉得你的Java项目是一个Maven项目:
awk -F'src/main/java/' 'NF==2{split($1,a,"/");j=p=$2;sub(/.*\//,"",j);sub("/[^/]*$","",p);gsub("/",".",p);print a[2]"."a[3],p,j}' yourlog
用你的例子来测试一下:
kent$ cat f1
------------------------------------------------------------------------
r12345 | debajyoti.das@email.com | 2013-02-07 01:27:08 -0800 (Thu, 07 Feb 2013) | 1 line
Changed paths:
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/Main.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleGroupTask.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleProcessTaskBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.agent/src/main/java/com/companyname/cycle/agent/bll/tasks/CycleSequenceProcessTaskBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/cycle.test/src/main/java/com/companyname/cycle/test/bll/MockCycleBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/pas.cycle/src/main/java/com/companyname/pas/cycle/bll/DasCycleBll.java
M /PROJECT/CYCLE/branches/DEV_Branch/pas.cycle/src/main/java/com/companyname/pas/cycle/dal/DasCycleDal.java
BUG ID 12345678 - BLAH IMPLEMENTATION IN PROJECT.CYCLE
------------------------------------------------------------------------
kent$ awk -F'src/main/java/' 'NF==2{split($1,a,"/");j=p=$2;sub(/.*\//,"",j);sub("/[^/]*$","",p);gsub("/",".",p);print a[2]"."a[3],p,j}' f1
PROJECT.CYCLE com.companyname.cycle.agent Main.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleGroupTask.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleSequenceProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.test.bll MockCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.bll DasCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.dal DasCycleDal.java
1
这是一个可以运行 svn log
命令并解析输出的版本。
当然,我没有你的代码库,所以我只能假装执行这个命令,输出结果也是假装的,只是用 cat
命令显示了你的输出,但它是可以工作的。
use strict;
my $revno = shift @ARGV;
die "Usage: $0: svn-revision\n" unless $revno;
my $cmd = "svn log -v -r$revno 'http://svn-remote.com/path'";
open(SVN,"$cmd |") or die "Command '$cmd' Failed : $!\n";
while(<SVN>) {
chomp;
if ( /^\s+\S\s\/([^\/]+\/[^\/]+).*[^\/]$/ ) {
(my $tag = $1) =~ s!/!.!g;
s!.*/src/main/java/!!;
my @a = split(/\//);
my $file = pop @a;
print $tag, " ", join(".", @a), " ", $file, "\n";
}
}
这是我的测试输出。
PROJECT.CYCLE com.companyname.cycle.agent Main.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleGroupTask.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleSequenceProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.test.bll MockCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.bll DasCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.dal DasCycleDal.java
一个 Maven 代码库里也会有一个 src/test/java
目录 :D,我猜你对这些不感兴趣。
编辑
运行 Perl 代码的主体,基本上是从另一个问题中添加 my $cmd = "sh fake.sh";
,得到的结果是:
PROJECT.CYCLE com.companyname.cycle.agent Main.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleGroupTask.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.agent.bll.tasks CycleSequenceProcessTaskBll.java
PROJECT.CYCLE com.companyname.cycle.test.bll MockCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.bll DasCycleBll.java
PROJECT.CYCLE com.companyname.pas.cycle.dal DasCycleDal.java
PROJECT.SHARED com.companyname.extensibility NamedExtensionPoint.java
PROJECT.SHARED com.companyname.extensibility PrePostExtensionPoint.java
PROJECT.SHARED com.companyname.extensibility.helper ExtensionConfigurationHelper.java
PROJECT.SRE com.companyname.ext DocumentGeneratorExt.java
PROJECT.SRE com.companyname.ext NamedExtensionPoint.java
PROJECT.SRE com.companyname.ext SystemDateBll.java
MODULE.CYCLE com.companyname.extensibility FileCycle1.java
MODULE.CYCLE com.companyname.extensibility FileCycle2.java
这似乎正是提问者在另一个问题中想要的结果。
所以问题在于需要对每个 $revno
循环执行 Perl 代码的主体。
foreach my $revno (@ARGV) {
print $revno, "\n";
}
编辑 将代码的主体按模块分组改为...
my %info;
while(<SVN>) {
chomp;
if ( /^\s+\S\s\/([^\/]+\/[^\/]+).*[^\/]$/ ) {
(my $tag = $1) =~ s!/!.!g;
s!.*/src/main/java/!!;
my @a = split(/\//);
my $file = pop @a;
print $tag, " ", join(".", @a), " ", $file, "\n";
push @{$info{$tag}}, join(" ", join(".", @a), $file);
#push @{$info{$tag}}, $file;
}
}
while ( my ($key, $value) = each %info )
{
print "$key\n";
for my $line ( @{$info{$key}} ) {
print "\t", $line, "\n";
}
}
在之前给出的数据上会产生这个结果。
PROJECT.SHARED
com.companyname.extensibility NamedExtensionPoint.java
com.companyname.extensibility PrePostExtensionPoint.java
com.companyname.extensibility.helper ExtensionConfigurationHelper.java
PROJECT.CYCLE
com.companyname.cycle.agent Main.java
com.companyname.cycle.agent.bll.tasks CycleGroupTask.java
com.companyname.cycle.agent.bll.tasks CycleProcessTaskBll.java
com.companyname.cycle.agent.bll.tasks CycleSequenceProcessTaskBll.java
com.companyname.cycle.test.bll MockCycleBll.java
com.companyname.pas.cycle.bll DasCycleBll.java
com.companyname.pas.cycle.dal DasCycleDal.java
MODULE.CYCLE
com.companyname.extensibility FileCycle1.java
com.companyname.extensibility FileCycle2.java
PROJECT.SRE
com.companyname.ext DocumentGeneratorExt.java
com.companyname.ext NamedExtensionPoint.java
com.companyname.ext SystemDateBll.java
这应该能在一定程度上帮助提问者实现他们想要的目标。