Subversion Repositories DevTools

Rev

Rev 1295 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1293 dpurdie 1
#!c:/perl/bin/perl.exe -w
2
 
3
###############################################################################
4
# Codestriker: Copyright (c) 2001 - 2004 David Sitsky.  All rights reserved.
5
# sits@users.sourceforge.net
6
#
7
# This program is free software; you can redistribute it and modify it under
8
# the terms of the GPL.
9
 
10
# Perl script for creating a single diff file over a Visual SourceSafe
11
# project, in a suitable form that can be input as a Codestiker
12
# (http://codestriker.sourceforge.net) topic.
13
 
14
###############################################################################
15
# Script configuration.
16
 
17
# If no argument is passed to the script, this is the SourceSafe
18
# project which will be used.  Modify this to reflect your own usage.
19
my $ss_project = '$/Project';
20
 
21
# Set this to the path of your ss.exe executable.
22
my $ss = 'C:/Program Files/Microsoft Visual Studio/VSS/win32/ss.exe';
23
 
24
# Specify the SS username and password to use when running ss.exe
25
# commands.
26
my $ss_username = 'admin';
27
my $ss_password = 'password';
28
 
29
# Specify the location of the SS repository.  If this is left empty
30
# then the SSDIR environment variable will not be set, and ss.exe will
31
# use the default repository.
32
my $ssdir = '';
33
#my $ssdir = '\\\\VisualSourceSafeMachineName\\SharedRepositoryPath';
34
#my $ssdir = 'c:\\Program Files\\Microsoft Visual Studio\\VSS';
35
 
36
# Set this to 1 to see all the SS commands being executed.
37
my $verbose = 0;
38
 
39
# End script configuration.
40
###############################################################################
41
 
42
use strict;
43
use File::Temp qw/ tmpnam tempdir /;
44
 
45
# First, check if an argument has been passed, which overrides
46
# $ss_project.
47
if ($#ARGV == 0) {
48
    $ss_project = $ARGV[0];
49
} elsif ($#ARGV > 0) {
50
    print STDERR "usage: ssdiff.pl [SourceSafe Project] > file.txt\n";
51
    print STDERR "       SourceSafe Project defaulted to $ss_project\n";
52
    exit 1;
53
}
54
 
55
# Create a temporary directory where all of the temporary files
56
# will be written to.  This iwll be automatically removed when the
57
# script exits.
58
my $tempdir;
59
if (defined $Codestriker::tmpdir && $Codestriker::tmpdir ne "") {
60
    $tempdir = tempdir(DIR => $Codestriker::tmpdir, CLEANUP => 1);
61
}
62
else {
63
    $tempdir = tempdir(CLEANUP => 1);
64
}
65
 
66
# Set the SSDIR environment variable if necessary.
67
if (defined $ssdir && $ssdir ne '')
68
{
69
    $ENV{SSDIR} = $ssdir;
70
}
71
 
72
# Now execute an 'ss dir' command to determine what files are a part
73
# of this project.
74
if ($verbose) {
75
    print STDERR "\"$ss\" dir -y${ss_username},${ss_password}" .
76
	" -R -I-Y \"$ss_project\"\n";
77
}
78
open(VSS, "\"$ss\" dir -y${ss_username},${ss_password}" .
79
     " -R -I-Y \"$ss_project\" |") || die "Unable to run ss diff command: $!";
80
 
81
# Collect the list of filename and revision numbers into a list.
82
my @files = ();
83
my $current_dir = '';
84
my $top_dir;
85
while (<VSS>) {
86
    if (/^(\$\/.*):$/o) {
87
	# Entering a new top-level directory.
88
	$current_dir = $1;
89
	$top_dir = $1 unless defined $top_dir;
90
    } elsif (/^\$[^\/]/o) {
91
	# Sub-directory entry which can be skipped.
92
    } elsif (/^\d+ item/o) {
93
	# Item count line which can be skipped.
94
    } elsif (/^\s*$/o) {
95
	# Skip blank lines.
96
    } elsif (/^(.*)$/o) {
97
	# Actual file entry.
98
	push @files, "$current_dir/$1";
99
    }
100
}
101
close VSS;
102
 
103
my $top_dir_length = length($top_dir);
104
 
105
# Now for each text file, we need to run an 'ss diff' command to see
106
# what contents have changed.
107
for (my $i = 0; $i <= $#files; $i++) {
108
    # Determine if the file is a text file, and if not, skip it.
109
    # Also determine its version number.
110
    if ($verbose) {
111
	print STDERR "\"$ss\" properties \"$files[$i]\"" .
112
	    " -y${ss_username},${ss_password} -I-Y\n";
113
    }
114
    open(VSS, "\"$ss\" properties \"$files[$i]\"" .
115
	 " -y${ss_username},${ss_password} -I-Y |")
116
	    || die "Unable to run ss properties on $files[$i]\n";
117
    my $text_type = 0;
118
    my $version;
119
    while (<VSS>) {
120
	if (/Type:\s*Text/o) {
121
	    $text_type = 1;
122
	} elsif (/^  Version:\s+(\d+)\s/o) {
123
	    $version = $1;
124
	}
125
    }
126
    close(VSS);
127
    next if $text_type == 0;
128
    die "Couldn't get version for $files[$i]\n" unless defined $version;
129
 
130
    # Now need to construct the path to the real file from the SS path.
131
    # First we need to remove the project part from the full "path".
132
    my $real_file = substr($files[$i], $top_dir_length+1);
133
    if (! defined $real_file) {
134
	die "Can't extract filename from $files[$i] top_dir $top_dir\n";
135
    }
136
 
137
    # Translate the forward slashes to back slashes.
138
    $real_file =~ s/\//\\/g;
139
 
140
    # If there are no slashes in the filename, we need to add .\ in the
141
    # front.  Don't ask!
142
    if ($real_file !~ /\\/o) {
143
	$real_file = ".\\" . $real_file;
144
    }
145
 
146
    print STDERR "Diffing $real_file against $files[$i]\n";
147
 
148
    # Note the command has to be redirected to a file, otherwise the ss
149
    # command will wrap the lines.
150
    my $command_output = "$tempdir\\___output.txt";
151
    if ($verbose) {
152
	print STDERR "\"$ss\" diff -y${ss_username},${ss_password} -I-Y" .
153
	    " -DU3000X5 -O\"$command_output\" \"$files[$i]\" \"$real_file\"\n";
154
    }
155
    system("\"$ss\" diff -y${ss_username},${ss_password} -I-Y" .
156
	   " -DU3000X5 -O\"$command_output\" \"$files[$i]\" \"$real_file\"");
157
    if (open(VSS, $command_output)) {
158
	# Because ss doesn't include the version number of the file we are
159
	# diffing against, we have to do so here.
160
	my $first_line = <VSS>;
161
	chop $first_line;
162
	print STDOUT "$first_line;$version\n";
163
	while (<VSS>) {
164
	    print STDOUT $_;
165
	}
166
	close VSS;
167
    }
168
    unlink $command_output;
169
}
170
 
171