#!/usr/bin/perl -w
#
# PVCS to Perforce converter, top level wrapper (calls all other scripts)
#
# Copyright 1997 Perforce Software. All rights reserved.
# Written by James Strickland, July 1997
require 5.0;
use strict;
use lib '.';
use convert;
# Check for parameter to avoid asking questions
my $confirm = shift(@ARGV);
$confirm = "" if (!defined($confirm));
unlink("logfile.log") if($convert::debug_level>0); # nuke the logfile, if any
# check that p4 is operational, warn if version does not support -f
print "Running p4 info.\n";
my $p4info=convert::p4run(" info");
# note: p4 info prints errors to stderr, so we deduce an error from the lack
# of output saying anything about the server
if( $p4info !~ m@server@si) {
print "\np4 info returned an error which must be fixed before proceeding.
Check the installation section of the Perforce manual.
Most likely you haven't started a Perforce server or you haven't set P4PORT
to point to the server.
You can obtain Perforce documentation from http://www.perforce.com\n\n";
print "Here's what p4 info returned:\n$p4info" if($p4info);
exit(1);
}
if( $p4info =~ m@\nServer version:\s+[^\s]+/([0-9]+) @s) {
my $change_number = $1;
my $magic_number = 4761; # first release of 97.3
if( $change_number < $magic_number ) {
print "Detected Perforce server version with change number $change_number.
The PVCS converter requires a 97.3 or later server. You can download Perforce
from http://www.perforce.com/\n";
exit(2);
}
} else { # Server version line not recognized
print "The Perforce server version was not detected - either you have a really
old version (you can get the latest version from http://www.perforce.com)
or the format of the output of p4 info has changed and no one updated
this script to match (in which case, we'd appreciate it if you let us know
- send email to support\@perforce.com).
The PVCS converter requires a 97.3 or later server. You can download Perforce
from http://www.perforce.com/
";
if ($confirm !~ /\-[yY]/)
{
print "Do you wish to proceed with your existing server? (y/n) ";
exit(3) if(<STDIN> !~ /y/);
}
}
# Check that the user has permission to run p4 changes.
open(ERROR, "p4 changes -m 1 2>&1 |");
if (<ERROR> =~ m@"permission for this operation"@si) {
print "You do not have the proper permissions to run this converter.
Please check P4USER to make sure it is set properly. If P4USER is correct,
see your Perforce administrator to get the necessary permissions.\n";
close(ERROR);
exit(4);
}
# Timestamp
print "Conversion started " . scalar(localtime()) . "\n";
# check no opened files...
print "Checking for no opened files.\n";
if(convert::p4run(" opened")) {
print "************************** ERROR
You have a variety of opened files - conversion cannot proceed.
Please revert them and try again:
";
print convert::p4run(" opened");
exit(4);
}
# check that the depot is empty
print "Checking that the depot is empty.\n";
if(convert::p4run(" changes -m 1") || convert::p4run(" labels")) {
my $port = $p4info;
$port =~ s@.*\nServer address:\s*(\S+).*@$1@s;
print "The Perforce depot stored by the server at '$port' is not empty!
Running this import process will import changes with earlier timestamps than
existing changes in the depot. Be careful!!
";
if ($confirm !~ /-[yY]/)
{
print "Are you sure you want to proceed? ";
exit(4) if(<STDIN> !~ /y/);
}
}
# Check that the user has superuser or admin protections
if(convert::p4run("protect -o") =~ m@"permission for this operation"@si) {
print "You do not have superuser permissions for this Perforce repository.
The converter updates the date and time on imported changelists which requires
superuser or administrator permissions.
";
print "Are you sure you want to proceed? ";
exit(4) if(<STDIN> !~ /y/);
}
# set up user name and client
$ENV{P4PORT} = $convert::p4port;
$ENV{P4USER} = $convert::p4user;
$ENV{P4CLIENT} = $convert::p4client;
print "\nUsing port/client/user '$ENV{P4PORT}/$ENV{P4CLIENT}/$ENV{P4USER}'.\n\n";
my $client_view = "//$convert::depot/$convert::depot_root/... //$ENV{P4CLIENT}/$convert::depot_root/...\n";
print "...creating/updating client $ENV{P4CLIENT} with:\n";
print " root $convert::client_root.\n";
print " view $client_view\n";
my $form = convert::p4run(" client -o $ENV{P4CLIENT}");
# Update the root and view
$form =~ s@(\nRoot:\s*)\s+\S[^\n]*\n@$1 $convert::client_root@s;
$form =~ s@(\nView:\s*)\n\s+.*\n$@$1\n\t$client_view@s;
convert::p4run(" client -i", $form);
# find all files under the root (the equivalent of an ls -R >filelist)
print "Listing all files under $convert::root.\n";
open(FILELIST,">filelist") or die "can't open: $!\n";
if (!$convert::projects) {
list_files($convert::root);
} else {
my $proj;
foreach $proj (split(/\|/, $convert::projects)) {
list_files(convert::join_paths($convert::root, $proj));
}
}
close(FILELIST);
# Run vlog on all files in the whole tree (vlog given the argument @filelist)
# - warnings are redirected to the file vlogerrs
# NOTE: YOU CAN'T USE THE -q FLAG TO VLOG BECAUSE IT ELIMINATES ALL WARNINGS!
print "Extracting metadata from all PVCS archive files under $convert::root.\n";
runcmd("vlog -xevlogerrs \@filelist > pvcs_properties");
open(F,"vlogerrs");
die "vlog produced error output - see the file 'vlogerrs'" if(<F>);
close(F);
unlink("vlogerrs");
runcmd("perl readvlog.pl < pvcs_properties");
# Sort the metadata
print "Sorting the metadata. " . scalar(localtime()) . "\n";
runcmd("perl sortmeta.pl");
# Improve the metadata - group changes, etc.
print "Improving the metadata. " . scalar(localtime()) . "\n";
runcmd("perl improve.pl");
# And now, what you've all been waiting for..
print "Creating the Perforce depot. " . scalar(localtime()) . "\n";
runcmd("perl mkdepot.pl");
# Some post-processing
print "Sorting the mapping file. " . scalar(localtime()) . "\n";
runcmd("perl sortmap.pl");
# Timestamp
print "Conversion finished " . scalar(localtime()) . "\n";
# Verification step
if ($convert::perform_verify) {
print "\nVerifying the result. " . scalar(localtime()) . "\n";
runcmd("perl verify.pl");
}
# Timestamp
print "Conversion finished " . scalar(localtime()) . "\n";
sub list_files
{
my $rt=shift;
if(! -d $rt) {
print "The specified root $convert::root is not a directory!\n";
print "Edit the config file and try again.\n";
exit(4);
}
ls($rt);
}
sub ls
{
for (@_) {
(-d $_) ? ls(allfiles($_)) : print FILELIST "\"$_\"\n";
}
}
sub allfiles # glob function doesn't work on most PC OSs
{
my $dir=shift;
my ($file,@list);
opendir(DIR,"$dir") or die "can't open $dir: $!";
chomp($convert::arc_file_regex);
while(defined($file=readdir(DIR))) {
next if($file eq '.' || $file eq '..');
next unless( -d "$dir/$file"
|| $file =~ /$convert::arc_file_regex/
|| $convert::list_all_files);
push @list,"$dir/$file";
}
closedir(DIR);
return @list;
}
sub runcmd
{
my $cmd = shift;
my $result = system($cmd);
if ($result) {
die "***** Failed to run command: $cmd\n";
}
}