# 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'; getopts('hb:o:x:y: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; } 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); 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 (@test) = `p4 integ -n -i "$from#$i,#$i" "$to" 2>&1`; #print "p4 cmd: *p4 integ -n -i \"$from#$i,#$i\" \"$to\" 2>&1*\n"; unless (grep (/already integrated/, @test)) { push (@files, "$from#$i,#$i"); } } } 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); push (@{$users{$user}{$change}}, $files[$i]); } } } my (@emails); foreach (keys(%users)) { $output = `p4 users $_`; if ($output =~ /<(.*\@.*)>/) { push(@emails,$1); } } print "TO:\n".join(";",@emails)."\n\n\n"; if ($opt_c) { foreach $name (sort(keys(%users))) { foreach my $change (sort(keys(%{$users{$name}}))) { 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"; foreach $name (sort(keys(%users))) { print "$name\n"; # print name foreach my $change (sort(keys(%{$users{$name}}))) { print "\t$change\n"; # print changelist number # sort unique undef %saw; @saw{@{${$users{$name}}{$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 "\n"; print "$0 -b branch_spec -o \"-r\"\n"; print "$0 -x \/\/depot\/a\/... -y \/\/depot\/b\/...\n"; exit; }