#!/usr/local/bin/perl # clone project databases use Getopt::Long; unless($result=GetOptions("h", "source=s", "target=s", "force", "from=s", "nointeg")){ die "Illegal Input Options, -h for help\n"; } ($prog = $0) =~ s,.*/,,; $HELP="Usage: $prog -source -target "; unless($opt_source && $opt_target) { print "$HELP\n"; exit(1); } if($opt_h) { print "$HELP\n"; exit(0); } umask(002); $project=$ENV{"PROJECT"}; if (!defined($project)) { print "$prog: must set env variable PROJECT first\n"; exit(1); } $cmd = "p4 client -o cdsp4_integ | grep '^Root' > /dev/null 2>&1"; system($cmd); if ($? != 0) { print "$prog: dummy integration client cdsp4_integ does not exist!\nContact your cdsp4 administrator; cannot proceed with branch building.\n"; exit(1); } (@pdata)=split('/',$project); $proj=$pdata[3]; if (!defined($proj)) { print "$prog: env variable PROJECT is not correctly set\n"; exit(1); } $tempfile="/tmp/byob.$$"; print "Building physical tree for $proj\n"; print "Log file is $tempfile\n"; # Check for validity of source and target # expand source and target to follow physical syntax $sbranch=$opt_source; $tbranch=$opt_target; print "Source branch is $sbranch, target is $tbranch\n"; # Check to see if source branch exists $cmd="p4 branches | grep $sbranch > /dev/null"; system($cmd); if($? ne 0) { print "Error: couldn't locate the source branch\n"; exit(1); } # Don't overwrite a target branch $cmd="p4 branches | grep $tbranch > /dev/null"; system($cmd); if($? eq 0 && !$opt_force) { print "Error: target branch already exists\n"; exit(1); } # Define the location of the file relative to the tree root (site dependent variable) $blocation=""; # need to find the root of the branch client to begin $bclient=$sbranch."_client"; $cmd="p4 client -o $bclient | grep '^Root'"; open(CMD,"$cmd|") || die "error $cmd\n"; while() { chomp; ($ig,$broot)=split; } print "Source branch root is $broot\n"; if ($blocation eq "") { $oldbdir = $broot; } else { $oldbdir="$broot/$blocation"; } ($newbdir = $oldbdir) =~ s/$sbranch/$tbranch/; # Check for existing and writable new branch directory if (! -d "$newbdir" || ! -w "$newbdir") { die "New branch root directory $newbdir does not exist or is not writable\n"; } # Check for opened files in the source branch print "Getting check out status for $opt_source\n"; $cmd="(p4 opened -a //depot/$sbranch/... | grep '#' ) > /dev/null 2>&1"; system($cmd); if($? eq 0) { if (!$opt_force) { system("cdscheckouts -bname $sbranch"); print "\n\nError: *** Aborting byob build due to checkouts in $sbranch\n\n"; print "Suggestion: *** IF you know what you are doing, you can use the -force flag\n"; print "\t\tto force the creation of your target branch, but this is potentially\n"; print "\t\tvery dangerous. You have been warned.\n"; exit; } else { print "Detected checkouts in source branch...\n"; print "*** Force option activated ***\n"; print "Please confirm this operation (accept_knowingly/no):"; $line = ; chomp $line; if($line ne "accept_knowingly") { print "byob aborted by user request\n"; exit; } } } # Feeling emboldened, let's do the integrate print "Integrating the data...\n"; if($opt_nointeg) { print "No integrations will be performed\n"; } else { if($opt_from) { print "Changenumber source is $opt_from\n"; $cmd="p4 -c cdsp4_integ integ -v //depot/$sbranch/...\@$opt_from //depot/$tbranch/... >> $tempfile"; } else { $cmd="p4 -c cdsp4_integ integ -v //depot/$sbranch/... //depot/$tbranch/... >> $tempfile"; } print "$cmd\n"; system($cmd); print "Submitting the change, please wait, this can take some time due to sheer volume of data...\n"; # First check if there are any pending file to avoid null submits $cmd="p4 -c cdsp4_integ change -o | grep \\^Files > /dev/null"; system($cmd); if($? eq 0) { $cmd="p4 -c cdsp4_integ change -o | sed 's//Branch submit by byob ($tbranch $opt_from)/g' | p4 -c cdsp4_integ submit -i >> $tempfile"; system($cmd); } else { print "All revisions appear to be up to date...\n"; } } # Now let's do the Cadence stuff # Need to clone the clients using the clientmapper script print "Syncing Cadence databases, please wait...\n"; $cmd="projclientmapper $proj $opt_source $proj $opt_target >> $tempfile"; print "$cmd\n"; system($cmd); # Now, build the branch cds.lib and cds.p4clients file # and the .branchrc file $oldcdslib="$oldbdir/cds.lib"; $newcdslib="$newbdir/cds.lib"; $cmd="sed 's/$sbranch/$tbranch/g' < $oldcdslib > $newcdslib"; system($cmd); # # Make sure each INCLUDEd file in cds.lib with a pointer into the # branch actually exists here. Copy it from the source branch if not. # if (!open(C, "<$newcdslib")) { print "$prog: couldn't open the new cds.lib we just built!\n"; } else { while() { split($_); if ($_[0] eq "INCLUDE" && $_[1] =~ /$newbdir/) { if (! -f $_[1]) { ($src_file = $_[1]) =~ s/$newbdir/$oldbdir/; if (! -f $src_file) { print "$prog: WARNING: need to copy INCLUDEd file $src_file into the new branch directory, but source file does not exist. Is something wrong with the cds.lib?\n"; } else { print "$prog: INFO: copying cds.lib's INCLUDE file $_[1] from the source branch directory\n"; $cmd = "cp $src_file $newbdir"; system($cmd); } } } } close(C); } # cds.p4client $oldcdsp4="$oldbdir/cds.p4client"; $newcdsp4="$newbdir/cds.p4client"; $cmd="sed 's/$sbranch/$tbranch/g' < $oldcdsp4 > $newcdsp4"; system($cmd); # .branchrc.il $branchrc="$newbdir/.branchrc.il"; open(BF,">$branchrc") || die "Could not write $branchrc\n"; print BF "setShellEnvVar(\"PROJECT_BRANCH=$tbranch\")\n"; close(BF); # build the branch spec to drive addnewbranch $desc="Created by byob"; $dspec_source="//depot/$sbranch/..."; $dspec_target="//depot/$tbranch/..."; &build_branch($tbranch,$desc,$dspec_source, $dspec_target); # build the branch client too # Spec it out $cname=$tbranch."_client"; $dspec="//depot/$tbranch/... //$cname/...\n\t-//depot/$tbranch/cadence/... //$cname/cadence/...\n"; $root=$broot; $root=~s/$sbranch/$tbranch/g; $desc="$tbranch client"; # Call it &build_client($cname,$root,$desc,$dspec); # sync it print "Syncing the branch client...\n"; $cmd="p4 -c $cname sync >> $tempfile 2>&1"; #print "$cmd\n"; system($cmd); print "byob is done...\n"; exit(0); # Begin subroutine declarations sub build_branch() { my $bname=shift; my $desc=shift; my $dspec_s=shift; my $dspec_t=shift; print "Building branch $bname\n"; my $tmpfile="/tmp/byob.bf.$$"; open(CF, ">$tmpfile") || die "Couldn't write temp branch file\n"; print CF "Branch: $bname\n"; print CF "Description:\n\t$desc\n"; # accept default options print CF "View:\n\t$dspec_s $dspec_t\n"; close(CF); system("p4 branch -i < $tmpfile"); system("rm $tmpfile"); } sub build_client() { my $cname=shift; my $root=shift; my $desc=shift; my $dspec=shift; print "Building client $cname\n"; my $tmpfile="/tmp/byob.cf.$$"; open(CF, ">$tmpfile") || die "Couldn't write temp client file\n"; print CF "Client: $cname\n"; print CF "Description:\n\t$desc\n"; print CF "Root: $root\n"; # accept default options print CF "View:\n\t$dspec\n"; close(CF); system("p4 client -i < $tmpfile"); system("rm $tmpfile"); }