#! /usr/bin/perl use strict; use File::ReadBackwards; use Getopt::Long; use P4; # Should be invoked with a lock file wrapper, like FreeBSD's lockf, or # unixwiz.net's lockrun, to insure that there is no overlap between # periodic executions. # Assume Perforce configuration is controlled by a .p4config file # in the converter's Perforce client workspace. The p4 user doing # the conversion should have a previously instantiated ticket that # does not expire (user is member of a group that allows non-expiring # tickets). $ENV{'P4CONFIG'} = "config.p4"; # Assume SVN and convertion utilities are in /usr/local/bin $ENV{'PATH'} .= ":/usr/bin"; ### XXX Use getopt processing for this. my $localTimeZone = 'America/Pacific'; my $usersuffix = '-fbsd'; my $svnURL = "svn://svn.freebsd.org/base"; my $cvtRoot = '/home/nmorse/projects/freebsd'; my $revmapFile = $cvtRoot . '/changeMap.txt'; my $svnLogFile = $cvtRoot . '/svn_log.xml'; my $p4Client = $cvtRoot . '/p4_client'; my $config = $cvtRoot . '/config.txt'; my $configBak = $cvtRoot . '/config.bak'; my $svnRoot = $cvtRoot . '/svndepot'; my $batchSize = 2000; # This timeout needs to be long enough to transmit an # entire maximum sized revision, 5 min was too short for # 5000+ file changelist my $timeout = 600; # 10 minutes max to svnsync my $rc; my $cmd; # right trim function to remove trailing whitespace sub rtrim($) { my $string = shift; $string =~ s/\s+$//; return $string; } # Determine the last imported SVN revision that is recorded in $revmapFile. my $nextSvnImportRev = 1; if( my $fh = File::ReadBackwards->new( $revmapFile ) ) { my $line = "#"; while ( substr( $line, 0, 1 ) == "#" ) { $line = $fh->readline; } print "line is: $line \n" ; my @values = split(',',$line); $nextSvnImportRev = $values[0] + 1; if ( $nextSvnImportRev =~ /\D/ ) { print "Unable to determine last imported SVN revision, defaulting to '0'\n"; $nextSvnImportRev = 1; } } # Determine the last revision in the local SVN repository. my $lastSvnRev = rtrim(`svnlook youngest $svnRoot`); die "Unable to determine latest SVN revision" unless defined($lastSvnRev); print "Last synchronized SVN revision is $lastSvnRev\n"; print "Next import SVN revision will be $nextSvnImportRev\n"; # If we don't have enough data, call svnsync to get from remote SVN if (($nextSvnImportRev + $batchSize) >= $lastSvnRev) { # clear any sync-locks which may be hanging around system("svn pdel --revprop -r 0 svn:sync-lock file://$svnRoot"); $cmd = "./timeout3.sh -t $timeout svnsync sync file://$svnRoot --non-interactive --trust-server-cert" ; $rc = system($cmd); # die "svnsync failed: Exit status $rc" unless ($rc == 0); } # Determine the last revision in the updated local SVN repository. my $lastSvnRev = rtrim(`svnlook youngest $svnRoot`); die "Unable to determine latest SVN revision" unless defined($lastSvnRev); if( $lastSvnRev <= $nextSvnImportRev ) { print "Import already up to date. Exiting\n"; exit(0); } print "Last available SVN revision is $lastSvnRev\n"; if (($nextSvnImportRev + $batchSize) < $lastSvnRev) { $lastSvnRev = $nextSvnImportRev + $batchSize; } print "Importing SVN revisions $nextSvnImportRev - $lastSvnRev\n"; # Extract a Dump file for the specified revisions $cmd = "svnadmin dump $svnRoot --quiet --incremental -r $nextSvnImportRev:$lastSvnRev > current.dump"; print "Running: $cmd\n"; $rc = system($cmd); die "svn dump extraction failed: Exit status $rc" unless ($rc == 0); # Operate from the root of the Perforce client in which we are performing # the conversion. This allows us to make use of any P4CONFIG based # configuration settings. chdir $p4Client; # Save most recent Perforce changeset number. This allows us to limit # the number of revisions changemap_search.pl must process to only those # created during this run. my $p4 = new P4; $p4->SetCwd($p4Client); $p4->Connect() or die( "Failed to connect to Perforce Server. Verify P4CONFIG setup.\n" ); my $lastP4Rev = $p4->RunCounter('change')->[0]->{ 'value' }; $p4->Disconnect(); print "last Perforce change ID was: $lastP4Rev \n"; # create a new config.txt with correct svn start and end parameters $rc = system("mv -f $config $configBak"); die "unable to move config file: Exit status $rc" unless ( $rc == 0) ; open( OUT, ">$config"); open( IN, "$configBak"); while (){ if (! (($_ =~ m/com.p4convert.svn.start/) || ($_ =~ m/com.p4convert.svn.end/) || ($_ =~ m/^\s*$/))) { print (OUT $_); } } close IN; print OUT "com.p4convert.svn.start=$nextSvnImportRev\n" ; print OUT "com.p4convert.svn.end=$lastSvnRev\n" ; close OUT; # Import revisions into Perforce. chdir $cvtRoot; $rc = system("/usr/bin/time java -Xmx65536M -jar p4convert-java.jar config.txt"); die "p4convert-svn failed: Exit status $rc" unless ($rc == 0); die "Run Completed\n"; exit(0);