#!/usr/bin/perl -w # -*- perl -*- use P4CGI ; use strict ; # ################################################################# # CONFIGURATION INFORMATION # All config info should be in P4CGI.pm # ################################################################# # # P4 label diff viewer # View diff between two labels # ################################################################# # Define variables set by command arguments my $label1 ; # Labels to diff my $label2 ; my $showSame ; # defined if files that are the same in both labels # should be listed my $showNotSame ; # defined if files that are not the same in botha labels # should be listed my $showDiff ; # defined if files that exists only in one of the labels # shold be displayed # Get arguments $label1 = P4CGI::cgi()->param("LABEL1") ; &P4CGI::bail("No label first specified") unless defined $label1 ; $label2 = P4CGI::cgi()->param("LABEL2") ; &P4CGI::bail("No label second specified") unless defined $label2 ; $showSame = P4CGI::cgi()->param("SHOWSAME") ; undef $showSame if $showSame ne "Y" ; $showNotSame = P4CGI::cgi()->param("SHOWNOTSAME") ; undef $showNotSame if $showNotSame ne "Y" ; $showDiff = P4CGI::cgi()->param("SHOWDIFF") ; undef $showDiff if $showDiff ne "Y" ; # # Start page # print "", &P4CGI::start_page("Diff between label
$label1 and $label2","") ; # Define a typeglob for use as file handle local *P4 ; # # Get basic data for labels # my ($date1,$time1,$owner1,$desc1,$opt1,$view1,@view1) = &getLabelData($label1) ; my ($date2,$time2,$owner2,$desc2,$opt2,$view2,@view2) = &getLabelData($label2) ; # # Print basic label data # print "", # Start table &P4CGI::start_table(""), &P4CGI::table_row(-type => "th", -bgcolor=>"white", "",$label1,$label2), &P4CGI::table_row({-align => "right", -text => "Date:"}, {-bgcolor => "white", -text => "$time1 $date1"}, {-bgcolor => "white", -text => "$time2 $date2"}); if($owner1 eq $owner2) { print "", &P4CGI::table_row({-align => "right", -text => "Owner:"}, undef, {-bgcolor => "white", -align => "center", -text =>$owner2}); } else { print "", &P4CGI::table_row({-align => "right", -text => "Owner:"}, {-bgcolor => "white", -text =>$owner1}, {-bgcolor => "white", -text =>$owner2}); } if($desc1 eq $desc2) { print "", &P4CGI::table_row({-align=>"right", -valign=>"top", -text=>"Description"}, undef, {-bgcolor => "white", -text =>$desc2}); } else { print "", &P4CGI::table_row({-align=>"right", -valign=>"top", -text=>"Description"}, {-bgcolor => "white", -text =>$desc1}, {-bgcolor => "white", -text =>$desc2}); } if(( $opt1 ne "") or ( $opt2 ne "")) { if($opt1 eq $opt2) { print "", &P4CGI::table_row({-align => "right", -text => "Options:"}, undef, {-bgcolor => "white", -text =>$opt2}); } else { print "", &P4CGI::table_row({-align => "right", -text => "Options:"}, {-bgcolor => "white", -text =>$opt1}, {-bgcolor => "white", -text =>$opt2}); } } ; if($view1 eq $view2) { print "", &P4CGI::table_row({-align => "right", -valign=>"top", -text => "View:"}, undef, {-bgcolor => "white", -text =>$view2}); } else { print "", &P4CGI::table_row({-align => "right", -valign=>"top", -text => "View:"}, {-bgcolor => "white", -text =>$view1}, {-bgcolor => "white", -text =>$view2}); } print "", &P4CGI::end_table(), "
"; # # Get files for labels # my (@lfiles1,@lfiles2); my %files1 ; my $v ; my @tmp1 ; foreach $v (@view1) { &P4CGI::p4call(*P4, "files $v\@$label1" ); while() { push @tmp1,$_ ; $_ =~ s/\#(\d+).*// ; ; $files1{$_} = $1 ; } close P4 ; } ; @lfiles1 = sort @tmp1 ; my @tmp2 ; my $commonFound=0 ; my $commonAndSameRev=0 ; foreach $v (@view2) { &P4CGI::p4call(*P4, "files $v\@$label2" ); while() { push @tmp2,$_ ; $_ =~ s/\#(\d+).*// ; my $otherRev = $files1{$_} ; if(defined $otherRev) { $commonFound++ ; $commonAndSameRev++ if ($otherRev == $1) ; } } close P4 ; } ; @lfiles2 = sort @tmp2 ; my ($nfiles1,$nfiles2) ; $nfiles1 = @lfiles1 ; $nfiles2 = @lfiles2 ; my $fileslisted = "Yes" ; print "Label \"$label1\" has $nfiles1 files
", "Label \"$label2\" has $nfiles2 files
", "Label \"$label1\" and \"$label2\" has $commonFound file", $commonFound==1?"":"s", " in common ($commonAndSameRev with same revision)
"; if($commonFound == 0) { print "", "The two labels has no files in common, comparsion aborted." ; } else { if(defined $showSame and defined $showNotSame and defined $showDiff) { print "Files:
\n" ; } elsif(!defined $showSame and !defined $showNotSame and !defined $showDiff) { print "No files listed!
\n" ; $fileslisted = undef ; } else { print "Listed files are:
\n" ; defined $showSame and do { print "
  • Files not modified\n" ; } ; defined $showNotSame and do { print "
  • Modified files (different rev.)\n" ; } ; defined $showDiff and do { print "
  • Files only in one of the labels $label1 and $label2\n" ; } ; print "\n" ; } ; # # Start print list of files # if(defined $fileslisted) { print "", &P4CGI::start_table("border bgcolor=white"), &P4CGI::table_row("-type","th", "File",undef,"$label1
    Rev.",undef,"$label2
    Rev.") ; my $f1 = shift @lfiles1 ; my $f2 = shift @lfiles2 ; while(defined $f1 or defined $f2) { my ($name1,$rev1,$name2,$rev2) = ("",0,"",0) ; if(defined $f1) { $f1 =~ /^([^\#]+)\#(\d+)/ ; $name1 = $1 ; $rev1 = $2 ; } if(defined $f2) { $f2 =~ /^([^\#]+)\#(\d+)/ ; $name2 = $1 ; $rev2 = $2 ; } if($name1 eq $name2) { if((defined $showSame and ($rev1 == $rev2)) or (defined $showNotSame and ($rev1 != $rev2))) { if($rev1 == $rev2) { print &P4CGI::table_row(&P4CGI::ahref("-url",&P4CGI::FLV_URL(), "FSPC=$name1","$name1"), undef,undef,undef, {-text=>" $rev1 ", -align=>"center"}) ; } else { print &P4CGI::table_row(&P4CGI::ahref("-url",&P4CGI::FLV_URL(), "FSPC=$name1","$name1"), {-text=>"$rev1", -align=>"center"}, undef, {-text=>&P4CGI::ahref("-url",&P4CGI::FDV_URL(), "FSPC=$name1", "REV=$rev1", "REV2=$rev2", "ACT=edit", "<->"), -align=>"center"}, {-text=>"$rev2", -align=>"center"}) ; } } if(defined $f1) { $f1 = shift @lfiles1 ;} ; if(defined $f2) { $f2 = shift @lfiles2 ;} ; } elsif (($name2 ne "") and ($name1 eq "" or $name1 gt $name2)) { if(defined $showDiff) { print &P4CGI::table_row(&P4CGI::ahref(-url => &P4CGI::FLV_URL(), "FSPC=$name2","$name2"), undef, {-text => "----", -align => "center", -bgcolor => "red"}, undef, {-text => "$rev2", -align => "center"}) ; } $f2 = shift @lfiles2 if(defined $f2) ; } else { if(defined $showDiff) { print &P4CGI::table_row(&P4CGI::ahref("-url",&P4CGI::FLV_URL(), "FSPC=$name1","$name1"), undef, {-text => "$rev1", -align => "center"}, undef, {-text => "----", -align => "center", -bgcolor => "red"}) ; } $f1 = shift @lfiles1 if(defined $f1) ; } } print "", &P4CGI::end_table() ; } } print &P4CGI::end_page() ; ### ### Subroutines ### # # Get label data. # Returns list containg "Mod date","mod time","owner","description","view" # sub getLabelData($ ) { my $label = shift @_ ; local *P4 ; my ($date,$time,$owner,$desc,$options,$view,@view) ; # Mod. date, mod. time, owner, description, view &P4CGI::p4call( *P4, "label -o $label" ); # Get label, time, date, owner while() { chop ; $_ = P4CGI::fixSpecChar($_) ; /^Label:\s+(\S+)/ && do { $label=$1 ; next ; } ; /^Date:\s+(\S+)\s+(\S+)/ && do { $date=$1 ; $time=$2 ; next ; } ; /^Owner:\s+(\S+)/ && do { $owner=$1 ; next ; } ; /^Description:/ && do { last ;} ; } ; # Get description while() { chomp ; s/^\s+// ; next if /^\s*$/ ; /^Options:\s*(.*)/ and do { $options = $1 ; next ; } ; last if /^View:/ ; if(defined $desc) { $desc .= "
    \n$_" ; } else { $desc = $_ ; } } ; # Get view while() { chomp ; s/^\s+// ; s/\s+$// ; next if /^\s*$/ ; push @view,$_ ; if(defined $view) { $view .= "
    \n$_" ; } else { $view = $_ ; } } ; close P4 ; return ($date,$time,$owner,"$desc",$options,"$view",@view) ; }; # # That's it folks #