# perl script to parse out the output of p4 integ -n # to determine who has the responsibility to merge # remaining files # usage: # %tobemerged.pl -h # # assumes: # p4 is in path # akalaveshi@mahinetworks.com use Getopt::Std; # global declarations use vars qw'$opt_h $opt_b $opt_x $opt_y $opt_o $opt_c $opt_u'; getopts('hb:o:x:y:u:c') || usage(); if ($opt_h || ((!$opt_x || !$opt_y) && !$opt_b)) { usage(); } if ($opt_b && ($opt_x || $opt_y)) { print "options -x and -y cannot be used with option -b\n"; exit; } if ($opt_o && (!$opt_b)) { print "option -o can only be used with option -b\n"; exit; } # get the current user my @p4userList = grep( /^P4USER=/, `p4 set` ); my $p4user; for $i (@p4userList) { if ($i =~ /^P4USER=(\S+)/) { $p4user = lc($1); } } if ($opt_u) { $p4user="$opt_u"; } die "Could not discover your user name." if (!$p4user); print "(user=$p4user)\n"; my (@warning); my (@integ); if ($opt_y && $opt_x) { (@integ) = `p4 integ -n -i "$opt_x" "$opt_y" 2>&1`; } elsif ($opt_b) { (@integ) = `p4 integ -n -i -b $opt_b $opt_o 2>&1`; } #my (@files, %users); my @files; for $i (0..$#integ) { # need to have a range (i.e. #5,#5) chomp ($integ[$i]); $integ[$i] =~ s/([^,])\#(\d+)$/$1\#$2,\#$2/; my ($range1, $range2); my ($to, $from, $action); if ($integ[$i] =~ /(\/\/.*) - (.*) from (\/\/.*#\d+,?#?\d*)/) { $to = $1; $action = $2; $from = $3; } else { die "Parsing error: $integ[$i]\n\n"; } if ($action =~ /can't branch/ || $action =~ /can't delete/) { push (@warning, "'$from' was deleted or moved on $opt_x"); next; } chomp ($from); if ($from =~ /(.*)#(\d+),#(\d+)/) { $from = $1; $range1 = $2; $range2 = $3; } else { print "incorrect parsing (*$from*) (*$integ[$i]*)\n"; } $to =~ s/#\d+$//; for my $i ($range1..$range2) { my $cmd = 'p4 integ -n -i "' . $from . '#' . $i . ',#' . $i . '" "' . $to . '" 2>&1'; #my (@test) = `p4 integ -n -i "$from#$i,#$i" "$to" 2>&1`; #print $cmd my (@test) = `$cmd`; #print "p4 cmd: *p4 integ -n -i \"$from#$i,#$i\" \"$to\" 2>&1*\n"; unless (grep (/already integrated/, @test)) { push (@files, "$from#$i,#$i"); } } } my %userChanges; for $i (0..$#files) { @temp = `p4 changes -l "$files[$i]"`; my ($found) = 0; foreach (@temp) { next if /^$/; # skipping blank lines if( m|^Change (\d+) on [0-9/]+ by (.*)@| ) { $change = $1; # capture change number $user = $2; # capture user $user = lc($user); if ($user eq $p4user) { push (@{$userChanges{$change}}, $files[$i]); } } } } if ($opt_c) { foreach my $change (sort(keys(%userChanges))) { my (@desc) = `p4 describe -s $change`; my ($picture) = '@<<<<<<<<<<<<<<<<<<<<<<<'; #. '<' x 30; foreach my $line (@desc) { chomp ($line); last if ($line =~ /^Affected files \.\.\./); format STDOUT = ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ $line . write; } # sort unique undef %saw; @saw{@{${$users{$name}}{$change}}} = (); @sorted_files = sort keys %saw; # foreach $f (@sorted_files) { print "$f\n"; #print files } } print "\n"; } else { print "NAME\tCHANGE\tFILE\n\n"; print "$p4user\n"; # print name foreach my $change (sort(keys(%userChanges))) { print "\t$change\n"; # print changelist number # sort unique undef %saw; @saw{@{$userChanges{$change}}} = (); @sorted_files = sort keys %saw; # foreach $f (@sorted_files) { print "\t\t$f\n"; #print files } } } print "\n\n\n Warnings:\n"; print join ("\n", @warning); sub usage { # print usage print "NAME\n$0\n"; #print "DESCRIPTION\n \n"; print "OPTIONS\n"; print "\t-b\n\t\tbranch spec\n"; print "\t-c\n\t\tdisplay changelist description\n"; print "\t-h\n\t\tDisplay this page.\n"; print "\t-o\n\t\toptions ('-r', etc)\n"; print "\t-x\n\t\tfrom branch\n"; print "\t-y\n\t\tto branch\n"; print "\t-u\n\t\tuser whose changelists will be displayed.\n"; print "\n"; print "$0 -b branch_spec -o \"-r\"\n"; print "$0 -x \/\/depot\/a\/... -y \/\/depot\/b\/...\n"; exit; }