""" $Id: //guest/jeffery_g_smith/perforce/utils/sttop4/python/convert.py#4 $ StarTeam to Perforce Converter, top level wrapper (calls all other scripts) Copyright 1998 Perforce Software. All rights reserved. Based on VSStoP4: Written by James Strickland, April 1998 Maintained by Robert Cowham, since 2000 Updated to support StarTeam conversions and converted to Python: Jeffery G. Smith, MedPlus, Inc. 2004-2005 """ import sys import os import re def errout(err, msg, obj=None, p4c=None): print >> sys.stderr, msg if obj: print >> sys.stderr, obj if p4c: p4c.disconnect() sys.exit(err) minp4ver = 4761 minpyver = (2, 4, 0) if sys.version_info[:3] < minpyver: errout(1, '\nThis converter requires Python %d.%d.%d (found %d.%d.%d)\n' \ 'The latest version of Python can be downloaded from http://www.python.org' % (minpyver + sys.version_info[:3])) try: import win32api except ImportError: errout(1, '\nThis converter requires the PyWin32 module which can be downloaded from\n' \ ' http://starship.python.net/crew/mhammond/') try: import p4 except ImportError: errout(1, '\nThis converter requires the P4Python module which can be downloaded from\n' \ ' http://public.perforce.com/guest/robert_cowham/perforce/API/python/') import params def main(): # TODO: Start Logging if len(sys.argv) != 2: errout(1, 'usage: ' + sys.argv[0] + ' INI-file') inifile = sys.argv[1] try: converter = params.Converter(inifile) except ValueError, e: errout(1, '\nThe configuration file is missing or badly formatted.\n' + 'The following error was returned:\n\t', e) confirm = converter.getparam('conversion', 'confirm') p4client = p4.P4() p4client.parse_forms() p4client.port = converter.getparam('perforce', 'p4port') p4client.user = converter.getparam('perforce', 'p4user') p4client.client = converter.getparam('perforce', 'p4client') p4passwd = converter.getparam('perforce','p4passwd') if p4passwd: p4client.password = p4passwd # check that p4 is operational, and check for a supported version print 'Connecting to Perforce server...' try: p4client.connect() except p4.P4Client.error, e: errout(1, '\nUnable to connect to the Perforce server.\n' \ 'Check the value of p4port in the [perforce] serction of ' + inifile +\ '\nand make sure the server there has been started.\n' \ '\nCheck the installation section of the Perforce manual.\n' \ 'You can obtain Perforce documentation from http://www.perforce.com\n' \ '\nThis is the error that was returned:\n', e) # Older servers return different info version than newer ones: # older: a list a strings # newer: a dictionary print 'Checking Perforce server info...' p4info = p4client.run('info') if type(p4info[0]) == dict: p4info = p4info[0] p4verkey = 'serverVersion' else: p4tmp = p4info p4info = dict() for str in p4tmp: try: (var, val) = str.split(': ') except ValueError: val = '' p4info[var] = val p4verkey = 'Server version' for (var, val) in p4info.iteritems(): print '\t', var + ':', val try: p4verstr = re.split('[\/\s]',p4info.get(p4verkey)) p4ver = p4verstr[2] change_number = int(p4verstr[3]) except TypeError: errout(2, '\nThe Perforce server version was not detected.\n' \ '\nEither you have a really old version\n' \ 'or the format of the output of p4 info has changed\n' \ 'and no one updated this script to match.\n' \ 'If this is the case, please send email to support@perforce.com.\n' \ '\nThe converter requires a 97.3 or later server.\n' \ 'You can download Perforce from http://www.perforce.com/\n', p4c=p4client) if change_number < minp4ver: errout(2, '\nDetected Perforce server version with change number ' + p4ver +\ '\nThe StarTeam converter requires a 97.3 or later server.\n' \ 'You can download Perforce from http://www.perforce.com/\n', p4c=p4client) if confirm: if raw_input('Do you wish to proceed with your existing server? (y/n) ').lower() != 'y': sys.exit(3) # If there are files opened on this client, we can't construct changelists safely. print 'Checking for opened files...' try: opened_files = p4client.run('opened') except: if p4client.errors: errout(1, '\nUnable to connect to the Perforce server.\n' \ '\nThis is the error that was returned:\n' + '\n'.join(p4client.errors), p4c=p4client) raise if opened_files: files = '' for ofile in opened_files: files += '\t' + ofile['depotFile'] + '\n' errout(4, '\nYou have a opened files - conversion cannot proceed.\n', \ 'Please revert them and try again:\n' + files, p4c=p4client) # If the depot isn't empty, make sure the user wants to continue. print 'Checking that the depot is empty...' last_changelist = int(p4client.run('counter', 'change')[0]) labels = p4client.run('labels') if (last_changelist > 0) or labels: print >> sys.stderr, '************* WARNING *************\n', \ '\nThe Perforce depot stored by the server at\n', \ ' ', p4info['Server address'], \ '\nis not empty!\n', \ 'Running this import process will import changes with\n', \ 'earlier timestamps than existing changes in the depot.\n' \ 'Be careful!!\n' if confirm: if raw_input('Are you sure you want to proceed? (y/n) ').lower() != 'y': sys.exit(4) # Check if we are being asked to ignore changes - dangerous!! print 'Checking for changelist start time setting...' if converter.getparam('changelists', 'start'): print >> sys.stderr, '************* WARNING *************\n', \ 'You have specified a start value in the [changelists] section of ' + inifile +\ '\nThis is a time before which to ignore changelists.\n', \ 'This is potentially dangerous because if you have not correctly specified the\n', \ 'time stamp, you will get duplicate changelists!\n' if confirm: if raw_input('Are you sure you want to proceed? (y/n) ').lower() != 'y': sys.exit(4) # Check that the user has superuser or admin protections print 'Checking for administrative permissions...' try: p4client.run('protect', '-o') except: if p4client.errors[0] != "You don't have permission for this operation.\n": raise print >> sys.stderr, 'You do not have superuser permissions for this Perforce repository.\n' \ 'The converter updates the date and time on imported changelists\n' \ 'which requires superuser or administrator permissions.\n' if confirm: if raw_input('Are you sure you want to proceed? (y/n) ').lower() != 'y': sys.exit(4) # Timestamp print 'Conversion started ', scalar(localtime()) . "\n"; # 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); if ($convert::bypass_metadata) { # If a bypass is requested, verify that the files are there. $convert::bypass_metadata = -f "$convert::metadata_dir/files" && -f "$convert::metadata_dir/labels_summary" && -f "$convert::metadata_dir/changes"; } if ($convert::bypass_metadata) { print "BYPASSING the re-creation of the metadata/ files.\n"; } else { print "Extracting metadata... " . scalar(localtime()) . "\n"; print "...from all StarTeam projects at and below project: $convert::root\n"; runcmd("perl readhist.pl"); # 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"); # 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 runcmd { my $cmd = shift; convert::closelog(); my $result = system($cmd); if ($result) { die "***** Failed to run command: $cmd\n"; } convert::openlog('reopen'); } ''' if __name__ == '__main__': main()