# This module contains all code common to different phases of the # VSS to Perforce converter. require 5.0; package convert; use strict; use vars qw(@ISA @EXPORT); use integer; use Carp; use Cwd; require Exporter; @ISA = qw(Exporter); @EXPORT = qw( $metadata_dir $data_dir $root $client_root $time_interval $lowercase_pathnames $lowercase_filenames $lowercase_usernames $skip_ss_get_errors $bypass_metadata $debug_level run emkdir p4dir_and_file ); # set values of global variables $convert::metadata_dir = "metadata"; $convert::data_dir = "data"; # read the configuration file and set up needed variables my %option = read_form("config"); die "must specify root" unless exists($option{'root'}); $convert::root = forward_slash($option{'root'}); $convert::client_root = forward_slash(cwd() . "/" . $convert::data_dir); $convert::time_interval = (exists($option{'time_interval'})) ? $option{'time_interval'} : 600; $convert::lowercase_pathnames= (exists($option{'lowercase_pathnames'})) ? ($option{'lowercase_pathnames'} =~ /y/i) : 0; $convert::lowercase_filenames= (exists($option{'lowercase_filenames'})) ? ($option{'lowercase_filenames'} =~ /y/i) : 0; $convert::lowercase_usernames= (exists($option{'lowercase_usernames'})) ? ($option{'lowercase_usernames'} =~ /y/i) : 0; $convert::ss_options = (exists($option{'ss_options'})) ? $option{'ss_options'} : ""; $convert::debug_level = (exists($option{'debug_level'})) ? $option{'debug_level'} : 0; $convert::bypass_metadata= (exists($option{'bypass_metadata'})) ? ($option{'bypass_metadata'} =~ /y/i) : 0; $convert::skip_ss_get_errors= (exists($option{'skip_ss_get_errors'})) ? ($option{'skip_ss_get_errors'} =~ /y/i) : 0; # Run a command, optionally piping a string into it on stdin. # Returns whatever the command printed to stdout. The whole thing is # optionally logged. NOTE that stderr is not redirected. sub run { my ($syscall,$stuff_to_pipe_in) = @_; my $result; if(defined($stuff_to_pipe_in)) { # Use a temporary file because not all systems implement pipes open(TEMPFILE,">pipeto") or die "can't open pipeto: $!\n"; print TEMPFILE $stuff_to_pipe_in; close(TEMPFILE); $result = `$syscall <pipeto`; unlink("pipeto"); } else { $result = `$syscall`; } if($convert::debug_level > 0) { # append to a file - that way if the converter dies the file will # be up to date, and this mechanism doesn't rely on an open filehandle open(LOGFILE,">>logfile") or die "can't open logfile: $!"; print LOGFILE "\n\nCommand: $syscall\n"; print LOGFILE $result; close(LOGFILE); } return $result; } # Ensure a directory exists - make it and all required parents if it doesn't. # Die on failure. # Accepts a list of directories, makes them all with perms 0755 sub emkdir { my ($current,$prev,$dir); for (@_) { next if(length($_) < 2); # skip over drive letters and UNCs to avoid calling (eg) # mkdir a: or mkdir //machinename $prev= (/^[a-zA-Z]:/) ? 2 : ( (m@//@) ? index($_,'/',2) : 0); # mkdir for each subpath as necessary do { $current=index($_,'/',$prev+1); $dir= ($current == -1) ? $_ : substr($_,0,$current); if(! -d $dir) { mkdir($dir,0755) or croak "can't mkdir $dir: $!"; } $prev=$current; } while( $current != -1); } } sub read_form # read a Perforce style form { my $file = shift; my (%hash,$current_keyword); open(F,"<$file") or croak("can't open $file: $!"); while(<F>) { s/\s*#.*$//; # kill comments and any whitespace preceding the comment if(/^$/) { # empty line or line with just a comment undef($current_keyword); } elsif(substr($_,0,1) eq "\t") { croak("unrecognized line") if(!defined($current_keyword)); s/^\t//; $hash{$current_keyword} .= $_; } elsif(/(.*?):\s*(.*)/) { # keyword is everything up to the *first* colon $hash{$current_keyword=$1} = $2; } } close(F); return %hash; } sub forward_slash { my $s = shift; $s =~ s@\\@/@g; return $s; } # p4dir_and_file computes the directory and filename relative to the client root # given the VSS filename. sub p4dir_and_file { my $client_rel_dir = shift; $client_rel_dir =~ s%[\000-\031@#]%_%g; # convert unprintable, @, # to _ $client_rel_dir =~ s@^\$@main@; $client_rel_dir =~ s@/([^/]*)$@@; # strip off filename my $client_file = $1; $client_rel_dir = lc($client_rel_dir) if($convert::lowercase_pathnames); $client_file = lc($client_file ) if($convert::lowercase_filenames); return ($client_rel_dir,$client_file); } # return a string joining the pathname components, # ensuring there is one / between components and there is no trailing slash sub join_paths { my $path=""; for (@_) { if(defined($_) && $_ ne "") { $path .= (substr($_,-1) eq '/') ? $_ : $_ . '/'; } } chop($path) if(substr($path,-1) eq '/'); return $path; } # get the given file from VSS (specified as a complete "project" path) # and name it according to its name in Perforce (given client dir and filename) sub get_vss_file { my ($vss_file,$revision,$client_dir,$client_file) = @_; emkdir($client_dir); unlink($client_file); $revision = "-v$revision" if $revision; # if $revision not set, don't give -v flag (tempobj hack) convert::run("ss get \"$vss_file\" -W -GL\"${client_dir}\" $revision $convert::ss_options"); # get it writable so that we can unlink it later $vss_file =~ m@/([^/]*)$@; $vss_file = $1; # now it's just the filename part rename($vss_file,$client_file) unless($vss_file eq $client_file); } 1;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#22 | 16012 | Robert Cowham | Rename/move project to conform to new Workshop naming structure. | ||
#21 | 8593 | Robert Cowham |
- Updated to work with VSS 2005 - Switched docs to mention Strawberry Perl rather than ActiveState Perl |
||
#20 | 6404 | Robert Cowham |
- Convert to official P4Perl - Avoid appending to logfile.log - Tidy up label markers - Remove name clash on p4exec function |
||
#19 | 6244 | Robert Cowham |
- Merge in changes to cope with previously illegal chars in filenames %, *, #, @ (requires 2004.2 server and above) |
||
#18 | 5860 | Robert Cowham | - Improved logging slightly - new summary log file sumlogfile.log created | ||
#17 | 5681 | Robert Cowham |
- Fix compatibility problem with 2005.1 server - Added tests for all servers back to 2003.2 - Log more info about options used - Clarify the vss_user/password rather than put in ss_options |
||
#16 | 5308 | Robert Cowham | Make name of config file settable via environment VSSTOP4_CONFIG | ||
#15 | 5306 | Robert Cowham |
- Minor fix of error handling for non-scalar values - allow for depot_root to be empty - change convert.pl to use P4Perl only |
||
#14 | 4026 | Robert Cowham |
Make previous change configurable rather than hard-coding and add explanation to config.ini about it. Point Update section on web page to Changelog.txt |
||
#13 | 4024 | Robert Cowham | Make slightly more robust - ignore VSS prompts for input by using the -I- flag to commands. | ||
#12 | 4000 | Robert Cowham |
Remove changes for non-P4Perl version. Improved Web page with download links. |
||
#11 | 3925 | Robert Cowham | Problems as per Michael Shields when not using P4Perl. | ||
#10 | 3918 | Robert Cowham | Improve performance of logging. | ||
#9 | 3797 | Robert Cowham |
Remove warnings. Trim whitespace from ends of lines in config.ini entries |
||
#8 | 3639 | Robert Cowham |
Changed filetype and inserted ID string. Fixed typo. |
||
#7 | 3609 | Robert Cowham |
Integrate in changes for: - Use of DB_File for large hashes (if available) - Reworking of label algorithm - MUCH faster - Use of P4Perl (if available) - much faster - Use of VSS OLE Automation (if available) - sometimes faster See README.txt and Performance section for details. |
||
#6 | 3558 | Robert Cowham |
Fixed bug with French date formats. Autoupdate client root and view based on config.ini entries. |
||
#5 | 3553 | Robert Cowham |
Read date and time formats directly from Windows registry. Avoids problems with users forgetting to set or getting wrong. |
||
#4 | 2660 | Robert Cowham |
Allow labels to be ignored if not wanted using configurable regexp. Next change in this area is to make recreation of labels vastly quicker! |
||
#3 | 2167 | Robert Cowham |
Renamed files to use Windows conventions as most likely platform for a VSS conversion. |
||
#2 | 2165 | Robert Cowham | Merged in changes from Guest branch | ||
#1 | 2160 | Robert Cowham | Main version from .zip file from http://www.perforce.com/perforce/loadsupp.html#conv page |