我正在尝试编写一个Perl子例程,该子例程返回一个已修改并从$previous_date
提交到Perforce存储库的文件数组,直到now
。这是子程序的样子:
sub p4_files {
my ($previous_date) = @_;
my $files = "//depot/project/design/...rtl.sv"
my $p4cmd = "p4 files -e $files\@$previous_date,\@now";
my @filelist = `$p4cmd`;
chomp @filelist;
return @filelist;
}
如果在给定日期之间提交了文件,子例程将按预期工作。但是,没有进行任何新的更改,执行p4 files
命令会返回一条消息:
prompt% p4 files -e //depot/project/design/...rtl.sv\@25/05/2017,\@now
prompt% //depot/project/design/...rtl.sv\@25/05/2017,\@now - no revision(s) after that date.
我应该如何在Perl脚本中处理这个问题?我想在遇到这种情况时退出脚本。
答案 0 :(得分:1)
不幸的是,p4
返回退出代码0,无论它是否找到某些文件或是否返回“该日期之后没有修订”消息。这意味着你必须解析输出。
最简单的解决方案可能是退出脚本if $filelist[0] =~ / - no revision\(s\) after that date\./
。缺点是我们不知道该消息是多么“稳定”。 Perforce的未来版本是否会完全发出此消息,或者他们是否可以重新编写消息?
另一种选择是使用-s
开关:my $p4cmd = "p4 -s files -e $files\@$previous_date,\@now";
。这导致p4
在每行输出之前添加“严重性”。如果找到文件,该行将以info:
开头,而“该日期之后的无修订”将以error:
开头。这对我来说看起来更稳定:退出if grep /^error:/, @filelist
。注意最后一行;当您使用-s
开关时,您将获得一个带退出代码的额外行。
另一种选择是使用P4Perl。在这种情况下,您将获得结果作为结构化数据,这将避免解析。这可以说是最优雅的,但你首先需要P4Perl模块。
答案 1 :(得分:1)
我建议使用-F
标志来驯服输出:
my $p4cmd = "p4 -F %depotFile% files -e $files\@$previous_date,\@now";
然后继续:
my @filelist = `$p4cmd`;
good_bye() unless @filelist; # Say goodbye and exit.
如果没有包含@filelist
字段的输出行, %depotFile%
将为空,现在您的调用者不需要尝试解析标准{{{ 1}}输出。
如果您想进一步按下p4 files
输出,请查看p4 files
,以便了解可插入p4 -e files (args)
的不同字段。
答案 2 :(得分:0)
如果没有填充数组,则不执行任何操作。
my @filelist = `$p4cmd`;
good_bye() unless @filelist; # Say goodbye and exit.
chomp @filelist;
要取消该消息,只需将命令的stderr重定向到bitbucket:
my $p4cmd = "p4 files -e $files\@$previous_date,\@now 2> /dev/null";