Jon J
Jon J

Reputation: 445

Handling Perforce message in Perl when there are no new files submitted

I am trying to code a Perl subroutine that returns an array of files that has been modified and submitted to the Perforce repository from $previous_date until now. This is how the subroutine looks like:

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;
}

The subroutine works as expected if there are files submitted between the given dates. However, it happens that no new changes are made, and executing the p4 files command returns a message instead:

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.

How should I handle this in my Perl script? I would like to exit the script when such a situation is encountered.

Upvotes: 0

Views: 129

Answers (3)

Samwise
Samwise

Reputation: 71464

I suggest using the -F flag to tame the output:

my $p4cmd = "p4 -F %depotFile% files -e $files\@$previous_date,\@now";

and then go ahead with the:

my @filelist = `$p4cmd`;
good_bye() unless @filelist;  # Say goodbye and exit.

@filelist will be empty if there are no lines of output containing a %depotFile% field, and now your caller doesn't need to try to parse the depot path out of the standard p4 files output.

If you want to massage the p4 files output further, take a look at p4 -e files (args) so you can see what the different fields are that you can plug into -F.

Upvotes: 1

choroba
choroba

Reputation: 241918

Just do nothing if the array isn't populated.

my @filelist = `$p4cmd`;
good_bye() unless @filelist;  # Say goodbye and exit.

chomp @filelist;

To suppress the message, just redirect stderr of the command to a bitbucket:

my $p4cmd = "p4 files -e $files\@$previous_date,\@now 2> /dev/null";

Upvotes: 0

sferencik
sferencik

Reputation: 3249

Unfortunately, p4 returns exit code 0 regardless of whether it finds some files or whether it returns the "no revision(s) after that date" message. That means you have to parse the output.

The simplest solution is probably to exit the script if $filelist[0] =~ / - no revision\(s\) after that date\./. The downside is we don't know how "stable" that message is. Will future versions of Perforce emit this message exactly, or is it possible they would reword?

Another option is to use the -s switch: my $p4cmd = "p4 -s files -e $files\@$previous_date,\@now";. That causes p4 to prepend the "severity" before every line of output. If a file is found, the line will start with info:, while the "no revision(s) after that date" will start with error:. That looks a bit more stable to me: exit if grep /^error:/, @filelist. Watch out for the last line; when you use the -s switch, you get an extra line with the exit code.

Yet another option would be to use P4Perl. In that case you'd get the results as structured data, which will obviate the parsing. That's arguably the most elegant, but you'd need the P4Perl module first.

Upvotes: 1

Related Questions