#!/usr/bin/perl -w
# richHistory.pl
# This script provides access to each changelist that user usually can see in Perforce GUI client as a 'Revision Graph'
# for more information please use command `pod2text richHistory.pl`
# Author: Dmytro Gorbunov <dmitro.gorbunov@gmail.com>
use strict;
use Getopt::Long;
use Pod::Usage;
my %brs; #key - branch, value - undef - not checket yet, 0 - access denied, otherwise ref to array of submits
my $help;
my $naDirsFileName = 'naDirs.cache';
my $noCache = 0;
GetOptions('help|?' => \$help, 'nocache' => \$noCache) or pod2usage(2);
my $useCache = not $noCache;
pod2usage(1) if $help;
my $init = $ARGV[0];
$brs{$init} = undef;
sub observe
{
my ($path, $cl,$type,$date,$author,$comment) = @_;
foreach (@_) { s/^\s+//; s/\t/<TAB>/g; s/\n/<CR>/g; }
print join "\t", @_;
print "\n";
}
#---------------------------------------------------------
# p4/na.cache
my %prevDenied;
if ($useCache){
if (open (my $ifh, '<', $naDirsFileName) ){
local $/;
%prevDenied = map {$_ => 1 } split "\n", <$ifh>;
close $ifh;
}
}
#---------------------------------------------------------
my $needRedo = 1;
while ($needRedo == 1) {
$needRedo = 0;
while (my ($b, $val) = each %brs) {
next if defined $val;
my $out = qx{p4 filelog -l $b};
if ($out =~ /^$/) { $brs{$b} = 0; next} # no permitions
$needRedo = 1; # we've got real output!
my @sbs;
foreach ( $out =~ /^\.\.\. #(.*?)(?=^\.\.\. #|\Z)/msg) {
my $submit = $_;
my ($cl, $type, $date, $author) = $submit =~ /\A.*?change (\d+) (\w+) on (.*?) by (.*?) /;
my ($comment) = (split "\n\n", $submit)[1];
push @sbs, [$cl,$type,$date,$author,$comment];
foreach ($submit =~ /^\.\.\. .*?(\/\/.*?)#\d/mg){
my $path = $_;
# cut filename and check for folders that was denied
if (%prevDenied) { s{/[^/]+$}||; next if defined $prevDenied{$_}; }
$brs{$path} = undef unless defined $brs{$path}
}
}
$brs{$b} = \@sbs;
}
}
#---------------------------------------------------------
if ($useCache){
open (my $fh, '>>', $naDirsFileName) or die;
while (my ($b, $val) = each %brs) {
next unless $val eq '0';
# remove filename (TODO: remove as much as possible) and save for caching access denied responses
$b =~ s{/[^/]+$}||;
print $fh "$b\n";
}
}
#---------------------------------------------------------
while (my ($path, $data) = each %brs){
next if $data eq '0';
foreach (@$data){
observe($path, @$_);
}
}
__END__
=head1 NAME
richHistory.pl - This script extracts list of changelists (with some additional info) that user usually can see in P4V as a 'Revision Graph'
=head1 SYNOPSIS
richHistory.pl - This script extracts list of changelists (with some additional info) that user usually can see in P4V as a 'Revision Graph'
This script returns flat content of "Revision Graph" for futher analysis and usage.
Usage:
./richHistory.pl -help
./richHistory.pl //depot/branch/test.cpp
./richHistory.pl -nocache //depot/branch/test.cpp
Options:
-help help message
-nocache don't use cache for non-available pathes
=head1 OUTPUT
Output is tab-separated.
One line contains information about one submit.
The format is the following:
PATH CHANGELIST TYPE_OF_CHANGE DATE AUTHOR COMMENT
All tabs and new lines in comment(description of the submit) changed to '<TAB>' and '<CR>'
TYPE_OF_CHANGE can be add, branch, delete or integrate, for more details please look at p4 help