#!/usr/bin/perl -w # -*- perl -*- use P4CGI ; use strict ; # ################################################################# # CONFIGURATION INFORMATION # All config info should be in P4CGI.pm # ################################################################# # # P4 depot tree browser # ################################################################# ### ### Handle file spec argument ### # * Get path from argument my $fspc = P4CGI::cgi()->param("FSPC") ; $fspc =~ s/\.\.\.$// if defined $fspc ; # Find out if we have multiple depots my @depots ; my $err2null = &P4CGI::REDIRECT_ERROR_TO_NULL_DEVICE() ; &P4CGI::p4call(\@depots,"dirs \"//*\" $err2null") ; my $moreThanOneDepot = (@depots > 1) ; # Set server ROOT my $ROOT ; if($moreThanOneDepot) { $ROOT = "/" ; } else { $ROOT = "$depots[0]/" ; $ROOT =~ s|//|/|g ; } ; # canonicalize to either "/.../" or "/" $fspc = $ROOT unless defined $fspc ; $fspc = "/$fspc/" ; while($fspc =~ s|//|/|) {} ; # Find out if we are at root my $weAreAtROOT = ($fspc eq $ROOT) ; ### ### handle "Hide deleted files" argument ### # * Get HIDEDEL argument (Hide deleted files) my $hidedel = P4CGI::cgi()->param("HIDEDEL") ; $hidedel = "NO" unless defined $hidedel ; $hidedel = "YES" unless $hidedel eq "NO" ; my $p4DirsDOption = "" ; # Set -D option for "p4 dirs" if hide deleted $p4DirsDOption = " -D" if $hidedel eq "NO" ; ### ### Figure out "back" buttons ### my @back ; my $tmp = "$fspc" ; # Copy arg $tmp =~ s|[^/]+/$|| ; # Remove last subdir # while($tmp ne $ROOT) { $tmp =~ s|([^/]+)/$|| or last ; my $f = $1 ; unshift @back,&P4CGI::ahref("FSPC=$tmp$f", "HIDEDEL=$hidedel", "/$f") ; } ; unless($weAreAtROOT) { unshift @back,&P4CGI::ahref("FSPC=$ROOT", "HIDEDEL=$hidedel", "[ROOT]") ; } ### ### Create link to changes for all files below ### my $linkToAllbelow = &P4CGI::ahref(-url => "changeList.cgi", "CMD=changes", "FSPC=/$fspc...", "View changes") ; ### ### Create link to view changes for a specific user below this point ### my $linkToChangeByUser = &P4CGI::ahref(-url => "changeByUsers.cgi", "FSPC=/$fspc...", "View changes by user or group") ; ### ### Create link to search for pattern ### my $linkToPatternSearch = &P4CGI::ahref(-url => "searchPattern.cgi", "FSPC=/$fspc...", "Search for pattern in change descriptions") ; ### ### Create link to recently modified files ### my $recentlyModified = &P4CGI::ahref(-url => "filesChangedSince.cgi", "FSPC=/$fspc...", "Recently modified files") ; ### ### Create link to depot statistics ### my $depotStatistics = &P4CGI::ahref(-url => "depotStats.cgi", "FSPC=/$fspc...", "Depot Statistics") ; ### ### Get subdirs ### my @subdirs ; &P4CGI::p4call(\@subdirs,"dirs $p4DirsDOption \"/$fspc*\" $err2null") ; map { my $dir = $_ ; my $dirname ; ($dirname = $dir) =~ s|^.*/|/| ; $_ = P4CGI::ahref("FSPC=$dir", "HIDEDEL=$hidedel", $dirname) ; } @subdirs ; ### ### Get files ### my @files ; my @tmp ; &P4CGI::p4call(\@tmp,"files \"/$fspc*\" $err2null") ; @files = map { /([^\#]+)\#(.*)/ ; my $file=$1 ; my $info=$2 ; $file =~ s/^.*\/// ; my ($rev,$inf) = split / - /,$info ; my $pfile = "$file" ; my $prev ; if($inf =~ /^delete/) { $prev = "<STRIKE>$rev</STRIKE>"; if($hidedel eq "YES") { $pfile = undef ; } else { $pfile= "<STRIKE>$file</STRIKE>"; } } else { $prev = &P4CGI::ahref(-url => "fileViewer.cgi", "FSPC=/$fspc$file", "REV=$rev", "$rev") ; }; if($pfile) { $pfile = &P4CGI::ahref(-url => "fileLogView.cgi", "FSPC=/$fspc$file", "$pfile"). "<font color=#808080> \#</font>$prev" ; } ; defined $pfile?$pfile:() ; } @tmp ; ### ### Create link for "hide/view deleted files" ### my $toggleHide ; if($hidedel eq "YES") { $toggleHide = P4CGI::ahref("FSPC=/$fspc", "HIDEDEL=NO", "Show deleted files") ; } else { $toggleHide = P4CGI::ahref("FSPC=/$fspc", "HIDEDEL=YES", "Hide deleted files") ; } ### ### Set help target ### &P4CGI::SET_HELP_TARGET("depotTreeBrowser") ; ### ### Start page printout ### print "", &P4CGI::start_page("Depot Tree Browser", &P4CGI::ul_list("<b>Subdir</b> -- Descend to subdir", "<b>File</b> -- Show file log", "<b>Rev</b> -- View current revision", "$toggleHide")) ; my $sarg=$weAreAtROOT?"[ROOT]":"/$fspc" ; # replace // with [ROOT] # Print current directory print "<H2 align=center><TT>$sarg</TT></H2>" ; # Print "back buttons" if(@back > 0) { print &P4CGI::image("back.gif")," Back to: ", join(' ',@back) ; } ### # Make table with three columns # sub makeThreeColumns(@) { my $l = @_ ; my $len = int((@_+2)/3) ; while(@_ < ($len*3)) { push @_,"" ;} ; # To avoid error messages return join("\n",(&P4CGI::start_table(" COLS=4 width=100%"), &P4CGI::table_row({-valign => "top", -width => "10", -text => ""}, {-valign => "top", -text => join("<br>\n",@_[0..$len-1])}, {-valign => "top", -text => join("<br>\n",@_[$len..(2*$len)-1])}, {-valign => "top", -text => join("<br>\n",@_[(2*$len)..(3*$len)-1])}), &P4CGI::end_table())) ; } if($weAreAtROOT and $moreThanOneDepot) { print "<P><b>Depots</b>\n" ; if(@subdirs>0) { print makeThreeColumns(@subdirs) ; } } else { print "<P><b>Subdirs</b>\n" ; if(@subdirs>0) { print makeThreeColumns(@subdirs) ; } else { print "<br>[No more subdirectories]" ; } print "<P><b>Files</b>\n" ; if(@files>0) { print makeThreeColumns(@files) ; } else { print "<br>[No files in this directory]<br>" ; } } ; print "<hr>\n" ; print &P4CGI::start_table("bgcolor=". &P4CGI::HDRFTR_BGCOLOR(). " align=center cellpadding=0 cellspacing=2") ; print &P4CGI::table_row(-align=>"right", "$linkToAllbelow...") ; print &P4CGI::table_row(-align=>"right", "$linkToChangeByUser...") ; print &P4CGI::table_row(-align=>"right", "$linkToPatternSearch...") ; print &P4CGI::table_row(-align=>"right", "$recentlyModified...") ; print &P4CGI::table_row({-align=>"right", -text => "$depotStatistics..."}, "...for <tt>/$fspc...</tt> :") ; print &P4CGI::end_table() ; print "", &P4CGI::end_page() ; # # That's all folks #