#
# Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
# All rights reserved.
# This component and the accompanying materials are made available
# under the terms of the License "Eclipse Public License v1.0"
# which accompanies this distribution, and is available
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
# Initial Contributors:
# Nokia Corporation - initial contribution.
#
# Contributors:
#
# Description:
# Validate releasables
# See below for usage
#
use Getopt::Long;
use Cwd;
use FindBin;
use File::Path;
use lib "$FindBin::Bin";
use EvalidMD5 0.01;
use EvalidCompare;
my $passed=0;
my $failed=0;
GetOptions("c", "v", "l=s", "g", "f", "m", "u", "x=s@", "i=s@", "d=s");
$opt_v = $opt_v; # To keep -w quiet.
$opt_g = $opt_g; # To keep -w quiet.
$opt_f = $opt_f; # To keep -w quiet.
$opt_m = $opt_m; # To keep -w quiet.
$opt_u = $opt_u; # To keep -w quiet.
$opt_d = $opt_d; # To keep -w quiet.
unless ((@ARGV > 1) && (@ARGV < 4))
{
#........1.........2.........3.........4.........5.........6.........7.....
print <<USAGE_EOF;
Usage:
evalid [opts] file1 file2 -- compare two files
evalid [opts] dir1 dir2 -- recursively compare two trees
MD5 Usage:
evalid [opts] -g dir1 file1 -- recursively generate MD5 checksums
evalid [opts] -f listfile dir1 file1 -- create MD5 checksums of listed files
evalid [opts] -m file1 file2 -- compare two MD5 datafiles
The recursive form will take each file in the tree rooted at dir1,
determine its type, and using the appropriate comparison attempt to
compare it with the corresponding file in the tree rooted at dir2.
evalid file1 dir2 => evalid file1 dir2\\file1
evalid dir1 file2 => evalid dir1\\file1 file2
The opts parameter controls where the output goes:
-v -- verbose information about failed comparisons
-c -- print results to standard output
-l <logfile> -- append results to <logfile>
The default is equivalent to "-l evalid.lis"
MD5 Options in addition to standard options:
MD5 Generation options
-g -- generate MD5 of the dir1 and write to file1
-f -- generate MD5 of the files listed files and write to file1
The listfile must contain a list of files, one per line.
They should be specified relative to dir1 but should not
start in a directory seperator (\\)
Sub options for -g and -f
-x -- exclude a reqular expression from the list of files
-i -- include a regular expression in to the list of files
-d dump_dir -- generate the output used in the processing of dir1 content
into files of the same name, within the same directory
structure, under dump_dir. This option permits the manual
examination of the data EVALID uses for its comparison work.
MD5 Comparison option
-m -- compare the MD5's of the file1 against to file2
-u -- alternate output formats for comparison
suitable for upgrading the directory defined by file1
to have the same contents as the directory defined by file2
Note: The inclusion takes precedence over the exclusion.
Note: Standard option (-v) has no effect on MD5 operations.
Note: Standard option (-l) has no effect on the -u option.
USAGE_EOF
exit 1;
}
# Generate checksum option
if ($opt_g)
{
# Check $ARGV[0] is a directory
die "$ARGV[0] is not a directory" unless (-d $ARGV[0]);
# Check $ARGV[1] does not exist
die "$ARGV[1] already exisits" if (-e $ARGV[1]);
&EvalidMD5::MD5Generate($ARGV[0], $ARGV[1], \@opt_x, \@opt_i, undef, $opt_d);
exit (0);
}
if ($opt_f)
{
# Check $ARGV[0] is a directory
die "$ARGV[0] does not exist" unless (-e $ARGV[0]);
# Check $ARGV[1] is a directory
die "$ARGV[1] is not a directory" unless (-d $ARGV[1]);
# Check $ARGV[2] does not exist
die "$ARGV[2] already exists" if (-e $ARGV[2]);
&EvalidMD5::MD5Generate($ARGV[1], $ARGV[2], \@opt_x, \@opt_i, $ARGV[0], $opt_d);
exit (0);
}
# Compare checksum file option (alternate format for upgrades)
if ($opt_u)
{
my ($iCommon, $iLeftHeaders, $iRightHeaders, $iDiff);
# Check $ARGV[0] file exists
die "$ARGV[0] is not a file" unless (-f $ARGV[0]);
# Check $ARGV[1] does not exist
die "$ARGV[1] is not a file" unless (-f $ARGV[1]);
($iCommon, $iLeftHeaders, $iRightHeaders, $iDiff) = &EvalidMD5::MD5Compare($ARGV[0], $ARGV[1]);
$failed = &EvalidMD5::MD5CompareZipDel($iCommon, $iDiff, $ARGV[0], $ARGV[1]);
exit ($failed);
}
# Redirect output
if ($opt_c)
{
$log = \*STDOUT;
}
else
{
if (!$opt_l)
{
$opt_l = "evalid.lis";
}
open LOG, ">>$opt_l" or die "Cannot open logfile $opt_l\n";
$log = \*LOG;
}
# Compare checksum file option
if ($opt_m)
{
my ($iCommon, $iLeftHeaders, $iRightHeaders, $iDiff);
# Check $ARGV[0] file exists
die "$ARGV[0] is not a file" unless (-f $ARGV[0]);
# Check $ARGV[1] does not exist
die "$ARGV[1] is not a file" unless (-f $ARGV[1]);
($iCommon, $iLeftHeaders, $iRightHeaders, $iDiff) = &EvalidMD5::MD5Compare($ARGV[0], $ARGV[1]);
$failed = &EvalidMD5::MD5ComparePrint($iCommon, $iLeftHeaders, $iRightHeaders, $iDiff, $log);
exit ($failed);
}
# Make the comparison(s) Old Style
compare($ARGV[0], $ARGV[1]);
# Summarise the results
my $total=$passed+$failed;
if ($total > 1)
{
print $log "\nResults of evalid $ARGV[0] $ARGV[1]\n";
}
if (@missing)
{
if ($total>1)
{
printf $log "\n%d missing files\n\n", scalar @missing;
}
map {
print $log "MISSING: $_\n";
} @missing;
}
if (@failures)
{
if ($total>1)
{
printf $log "\n%d failed comparisons\n\n", scalar @failures;
}
map {
my ($left, $right, $type) = @{$_};
print $log "FAILED: $left\tand $right ($type)\n";
} @failures;
}
if ($total>1)
{
my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
printf $log "\n----------------\n%02d:%02d %02d/%02d/%04d\n", $hour, $min, $mday, $mon+1, $year+1900;
print $log "evalid $ARGV[0] $ARGV[1]\n";
if ($failed==0)
{
print $log "Passed all $total comparisons\n";
}
else
{
print $log "Failed $failed of $total comparisons\n";
}
print $log "----------------\n\n";
}
exit($failed==0);
#---------------------------------
sub identical
{
my ($left, $right, $type)=@_;
print $log "OK: $left\tand $right ($type)\n";
$passed+=1;
}
sub different
{
my ($left, $right, $type)=@_;
push @failures, [$left, $right, $type];
$failed+=1;
}
sub warning
{
my ($message)=@_;
print $log "WARNING: $message\n";
if (!$opt_c)
{
print "WARNING: $message\n";
}
# not a test failure as such
}
sub problem
{
my ($message)=@_;
print $log "PROBLEM: $message\n";
$failed+=1;
}
sub missing
{
my ($left) = @_;
push @missing, $left;
$failed+=1;
}
sub compare
{
my ($left, $right, $recursing) = @_;
if (-d $left && -d $right)
{
# Read all of the directory entries except . and ..
# in to a local list.
opendir LEFTDIR, $left or print "Cannot read directory $left\n" and return;
my @list = grep !/^\.\.?$/, readdir LEFTDIR;
closedir LEFTDIR;
# recurse
map {
compare($left."\\".$_, $right."\\".$_, 1);
} @list;
return;
}
if (-d $left)
{
if ($recursing)
{
if (-e $right)
{
problem("File $right should be a directory");
}
else
{
problem("Directory $right does not exist");
}
return;
}
compare($left."\\".$right,$right);
return;
}
if (-d $right)
{
if ($recursing)
{
problem("Directory $right should be a file");
return;
}
compare($left,$right."\\".$left);
return;
}
# comparing files
if (-e $left && !-e $right)
{
missing($right);
return;
}
if (!-e $left && -e $right)
{
problem("File $left does not exist");
return;
}
my ($same, $type) = EvalidCompare::CompareFiles($left, $right, $opt_v, $log);
if ($same)
{
identical($left, $right, $type);
}
else
{
different($left, $right, $type);
}
}