Rev 1293 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#!c:/perl/bin/perl.exe -w################################################################################ Codestriker: Copyright (c) 2001 - 2004 David Sitsky. All rights reserved.# sits@users.sourceforge.net## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Perl script for creating a single diff file over a Visual SourceSafe# project, in a suitable form that can be input as a Codestiker# (http://codestriker.sourceforge.net) topic.################################################################################ Script configuration.# If no argument is passed to the script, this is the SourceSafe# project which will be used. Modify this to reflect your own usage.my $ss_project = '$/Project';# Set this to the path of your ss.exe executable.my $ss = 'C:/Program Files/Microsoft Visual Studio/VSS/win32/ss.exe';# Specify the SS username and password to use when running ss.exe# commands.my $ss_username = 'admin';my $ss_password = 'password';# Specify the location of the SS repository. If this is left empty# then the SSDIR environment variable will not be set, and ss.exe will# use the default repository.my $ssdir = '';#my $ssdir = '\\\\VisualSourceSafeMachineName\\SharedRepositoryPath';#my $ssdir = 'c:\\Program Files\\Microsoft Visual Studio\\VSS';# Set this to 1 to see all the SS commands being executed.my $verbose = 0;# End script configuration.###############################################################################use strict;use File::Temp qw/ tmpnam tempdir /;# First, check if an argument has been passed, which overrides# $ss_project.if ($#ARGV == 0) {$ss_project = $ARGV[0];} elsif ($#ARGV > 0) {print STDERR "usage: ssdiff.pl [SourceSafe Project] > file.txt\n";print STDERR " SourceSafe Project defaulted to $ss_project\n";exit 1;}# Create a temporary directory where all of the temporary files# will be written to. This iwll be automatically removed when the# script exits.my $tempdir;if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne "") {$tempdir = tempdir(DIR => $Codestriker::tmpdir, CLEANUP => 1);}else {$tempdir = tempdir(CLEANUP => 1);}# Set the SSDIR environment variable if necessary.if (defined $ssdir && $ssdir ne ''){$ENV{SSDIR} = $ssdir;}# Now execute an 'ss dir' command to determine what files are a part# of this project.if ($verbose) {print STDERR "\"$ss\" dir -y${ss_username},${ss_password}" ." -R -I-Y \"$ss_project\"\n";}open(VSS, "\"$ss\" dir -y${ss_username},${ss_password}" ." -R -I-Y \"$ss_project\" |") || die "Unable to run ss diff command: $!";# Collect the list of filename and revision numbers into a list.my @files = ();my $current_dir = '';my $top_dir;while (<VSS>) {if (/^(\$\/.*):$/o) {# Entering a new top-level directory.$current_dir = $1;$top_dir = $1 unless defined $top_dir;} elsif (/^\$[^\/]/o) {# Sub-directory entry which can be skipped.} elsif (/^\d+ item/o) {# Item count line which can be skipped.} elsif (/^\s*$/o) {# Skip blank lines.} elsif (/^(.*)$/o) {# Actual file entry.push @files, "$current_dir/$1";}}close VSS;my $top_dir_length = length($top_dir);# Now for each text file, we need to run an 'ss diff' command to see# what contents have changed.for (my $i = 0; $i <= $#files; $i++) {# Determine if the file is a text file, and if not, skip it.# Also determine its version number.if ($verbose) {print STDERR "\"$ss\" properties \"$files[$i]\"" ." -y${ss_username},${ss_password} -I-Y\n";}open(VSS, "\"$ss\" properties \"$files[$i]\"" ." -y${ss_username},${ss_password} -I-Y |")|| die "Unable to run ss properties on $files[$i]\n";my $text_type = 0;my $version;while (<VSS>) {if (/Type:\s*Text/o) {$text_type = 1;} elsif (/^ Version:\s+(\d+)\s/o) {$version = $1;}}close(VSS);next if $text_type == 0;die "Couldn't get version for $files[$i]\n" unless defined $version;# Now need to construct the path to the real file from the SS path.# First we need to remove the project part from the full "path".my $real_file = substr($files[$i], $top_dir_length+1);if (! defined $real_file) {die "Can't extract filename from $files[$i] top_dir $top_dir\n";}# Translate the forward slashes to back slashes.$real_file =~ s/\//\\/g;# If there are no slashes in the filename, we need to add .\ in the# front. Don't ask!if ($real_file !~ /\\/o) {$real_file = ".\\" . $real_file;}print STDERR "Diffing $real_file against $files[$i]\n";# Note the command has to be redirected to a file, otherwise the ss# command will wrap the lines.my $command_output = "$tempdir\\___output.txt";if ($verbose) {print STDERR "\"$ss\" diff -y${ss_username},${ss_password} -I-Y" ." -DU3000X5 -O\"$command_output\" \"$files[$i]\" \"$real_file\"\n";}system("\"$ss\" diff -y${ss_username},${ss_password} -I-Y" ." -DU3000X5 -O\"$command_output\" \"$files[$i]\" \"$real_file\"");if (open(VSS, $command_output)) {# Because ss doesn't include the version number of the file we are# diffing against, we have to do so here.my $first_line = <VSS>;chop $first_line;print STDOUT "$first_line;$version\n";while (<VSS>) {print STDOUT $_;}close VSS;}unlink $command_output;}