diff -r 000000000000 -r 83f4b4db085c bldsystemtools/commonbldutils/check_tables.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bldsystemtools/commonbldutils/check_tables.pl Tue Feb 02 01:39:43 2010 +0200 @@ -0,0 +1,504 @@ +#!Perl -w + +use strict; +use Pod::Usage; +use Getopt::Long; +use FindBin; +use FileHandle; +use Net::SMTP; + +#--------------------------- GLOBAL VARIABLES ---------------------------# + +my $startDir = $FindBin::Bin; +my %componentList; #This has the components from the export table. +my @redundantComponents; #This is used by 2 methods. One populates it and + #the other reads it to remove the redundant + #components from the export table. + +# The location of the export tables +my $srcDir = $ENV{'SourceDir'}; +my $platform = $ENV{'Platform'}; +my $exportTableLocation = "$srcDir\\os\\deviceplatformrelease\\symbianosbld\\productionbldcbrconfig\\"; + + +my $help = 0; +my $man = 0; +my $autoclean = 0; +my $autoadd = 0; +my $email = 0; + +my @report; +my ($notification_address) = 'SysBuildSupport@symbian.com'; +my $message; + +# This has the components from the gt and tv components.txt +# We need to manually put into the hash the following because these +# are added by the release tools and are not explicitly mentioned in +# the GTComponents.txt or TechviewComponents.txt +my %mrpHashForProduct=( + "gt_techview_baseline" => 1, + "gt_only_baseline" => 1, + "gt_overwritten"=> 1, + "unresolved" => 1 + ); + +# Just specify the export tables for each product +my %exportTable = ( + "8.0a" => "AutoCBR_Tornado_test_export.csv", + "8.1a" => "AutoCBR_8.1a_test_export.csv", + "8.0b" => "AutoCBR_Zephyr_test_export.csv", + "8.1b" => "AutoCBR_8.1b_test_export.csv", + "9.0" => "AutoCBR_9.0_test_export.csv", + "9.1" => "AutoCBR_9.1_test_export.csv", + "9.2" => "AutoCBR_9.2_test_export.csv", + "9.3" => "AutoCBR_9.3_test_export.csv", + "Intulo" => "AutoCBR_Intulo_test_export.csv", + "Future" => "AutoCBR_Future_test_export.csv", + "9.4" => "AutoCBR_9.4_test_export.csv", + "9.5" => "AutoCBR_9.5_test_export.csv", + "9.6" => "AutoCBR_9.6_test_export.csv", + "tb92" => "AutoCBR_tb92_test_export.csv", + "tb92sf" => "AutoCBR_tb92sf_test_export.csv", + "tb101sf" => "AutoCBR_tb101sf_test_export.csv" + ); + +my %componentFiles = ( + "8.0a" => {"gtonly" => $exportTableLocation."8.0a\\gtcomponents.txt", + "tv" => $exportTableLocation."8.0a\\techviewcomponents.txt"}, + "8.0b" => {"gtonly" => $exportTableLocation."8.0a\\gtcomponents.txt", + "tv" => $exportTableLocation."8.0a\\techviewcomponents.txt"}, + "8.1a" => {"gtonly" => $exportTableLocation."8.1a\\gtcomponents.txt", + "tv" => $exportTableLocation."8.1a\\techviewcomponents.txt"}, + "8.1b" => {"gtonly" => $exportTableLocation."8.1b\\gtcomponents.txt", + "tv" => $exportTableLocation."8.1b\\techviewcomponents.txt"}, + "9.0" => {"gtonly" => $exportTableLocation."9.0\\gtcomponents.txt", + "tv" => $exportTableLocation."9.0\\techviewcomponents.txt"}, + "9.1" => {"gtonly" => $exportTableLocation."9.1\\gtcomponents.txt", + "tv" => $exportTableLocation."9.1\\techviewcomponents.txt"}, + "9.2" => {"gtonly" => $exportTableLocation."9.2\\gtcomponents.txt", + "tv" => $exportTableLocation."9.2\\techviewcomponents.txt"}, + "9.3" => {"gtonly" => $exportTableLocation."9.3\\gtcomponents.txt", + "tv" => $exportTableLocation."9.3\\techviewcomponents.txt"}, + "Intulo" => {"gtonly" => $exportTableLocation."Intulo\\gtcomponents.txt", + "tv" => $exportTableLocation."Intulo\\techviewcomponents.txt"}, + "Future" => {"gtonly" => $exportTableLocation."Future\\gtcomponents.txt", + "tv" => $exportTableLocation."Future\\techviewcomponents.txt"}, + "9.4" => {"gtonly" => $exportTableLocation."9.4\\gtcomponents.txt", + "tv" => $exportTableLocation."9.4\\techviewcomponents.txt"}, + "9.5" => {"gtonly" => $exportTableLocation."9.5\\gtcomponents.txt", + "tv" => $exportTableLocation."9.5\\techviewcomponents.txt"}, + "9.6" => {"gtonly" => $exportTableLocation."9.6\\gtcomponents.txt", + "tv" => $exportTableLocation."9.6\\techviewcomponents.txt"}, + "tb92" => {"gtonly" => $exportTableLocation."tb92\\gtcomponents.txt", + "tv" => $exportTableLocation."tb92\\techviewcomponents.txt"}, + "tb92sf" => {"gtonly" => $exportTableLocation."tb92sf\\gtcomponents.txt", + "tv" => $exportTableLocation."tb92sf\\techviewcomponents.txt"}, + "tb101sf" => {"gtonly" => $exportTableLocation."tb101sf\\gtcomponents.txt", + "tv" => $exportTableLocation."tb101sf\\techviewcomponents.txt"} + + + ); + + +#------------------------ END OF GLOBAL VARIABLES -----------------------# + + +# Utility function to print the keys of a hash ref (passed in). +sub printHash +{ + my $hashRef = shift; + + foreach my $line(sort keys %{$hashRef}) + { + push @report, $line."\n"; + print $line."\n"; + } +} + + + +# Compare the components in the export table against +# the components in the gt and tv components.txt files. +sub compareTables +{ + my $product = shift; + + my $dirty = 0; + foreach my $key (sort keys %componentList) + { + if(exists $mrpHashForProduct{$key}) + { + delete $mrpHashForProduct{$key}; + } + else + { + push @redundantComponents, $key; + } + } + if (scalar (@redundantComponents) != 0) + { + $dirty =1; + $message = "\n*** The following components can be removed from $exportTable{$product}:\n\n"; + print $message; + foreach my $line(@redundantComponents) + { + print $line."\n"; + } + } + + if (scalar keys %mrpHashForProduct != 0) + { + $dirty = 1; + $message = "\n*** The following components are missing from $exportTable{$product}:\n\n"; + push @report, $message; + print $message; + printHash(\%mrpHashForProduct); + + if ($email == 1) + { + &SendEmail("WARNING: For Symbian_OS_v$product: $exportTable{$product} is not up to date\n ",@report); + } + } + + if ($dirty == 0) + { + print "$exportTable{$product} is up to date\n"; + } +} +# Get the components that are listed in the export table for the +# product. + +sub getExportTableComponents +{ + + my $product = shift; + my $expTable = $exportTableLocation."$product\\".$exportTable{$product}; + + open(EXP_TABLE,"<$expTable") or die("Cannot open export table:\n$expTable"); + + foreach my $line () + { + if ($line =~ /\A([^\#,].+?),/) #Capture the component name. Ignore '#' or ',' if at beginning of line + { + $line = lc($1); + $line =~ s/\s+//g; + $line =~ s/\t+//g; + + if (not exists $componentList{$line}) + { + $componentList{$line} = 1; + } + else + { + print "Duplicate in export table: $line\n"; + } + } + } + close EXP_TABLE; +} + +# Get the components from the gt and techview components.txt +sub getComps +{ + my $tvfile = shift; + my $product = shift; + my $rv = shift; + + my @mrpContents = split /\n/, $rv; + + foreach my $componentsLine (@mrpContents) + { + my $component = lc((split /[\s\t]/, $componentsLine)[0]); + if (not exists $mrpHashForProduct{$component}) + { + $mrpHashForProduct{$component} =1; + } + else + { + print "Duplicate in gt/tv component: $component \n"; + } + } + undef @mrpContents; + + #We make the assumption that the techviewcomponents.txt is + #in the same location as the gtcomponents.txt for a given + #product. + open(TXT1, "<$tvfile") || die("Failed to find the components file for product $product"); + undef $/; + $rv = ; + close(TXT1); + + @mrpContents = split /\n/, $rv; + foreach my $componentsLine (@mrpContents) + { + my $component = lc((split /[\s\t]/, $componentsLine)[0]); + if (not exists $mrpHashForProduct{$component}) + { + $mrpHashForProduct{$component} =1; + } + else + { + print "Duplicate in gt/tv component: $component \n"; + } + } +} + +# Get the location where the gt and techview components.txt +# are in. Get the contents of the gtcomponents.txt. The +# contents of the techviewcomponents.txt are gotten in getComps +# function. +sub getGtAndTvFiles +{ + my $product = shift; + + my $rv; + my $gtfilename = $componentFiles{$product}->{"gtonly"}; + my $tvfilename = $componentFiles{$product}->{"tv"}; + + open(TXT2, "<$gtfilename") || die("Failed to find the components file for product $product"); + undef $/; + $rv = ; + close(TXT2); + + getComps($tvfilename, $product, $rv); + +# if ($rv !~ /no such file/) +# { +# my $tvfilename = "//EPOC/master/beech/product/tools/makecbr/files/$product/techviewcomponents.txt"; +# getComps($tvfilename, $product, $rv); +# return; +# } +# +# $gtfilename = "//EPOC/master/os/deviceplatformrelease/symbianosbld/productionbldcbrconfig/$product/gtcomponents.txt"; +# $rv = `p4 print -q $gtfilename 2>&1`; +# +# if ($rv !~ /no such file/) +# { +# my $tvfilename = "//EPOC/master/os/deviceplatformrelease/symbianosbld/productionbldcbrconfig/$product/techviewcomponents.txt"; +# getComps($tvfilename, $product, $rv); +# return; +# } +# die("Failed to find the Components file for product $product"); +} + +sub autoclean ($) +{ + my $product = shift; + my $expTable = $exportTableLocation."$product\\".$exportTable{$product}; + my %redundantComponentsHash; + + my $cleanexpTable = $exportTable{$product}; + $cleanexpTable =~ s/\.csv//; + $cleanexpTable = $startDir."\\"."${cleanexpTable}.csv"; + + if ($autoclean == 1) + { + print "********** Removing redundant components **********\n"; + } + #open the export table + open(INPUT, "<$expTable") or die ("Could not open $expTable for read\n"); + + #create the clean table + open(OUTPUT, ">$cleanexpTable") or die ("Could not create $cleanexpTable\n"); + + foreach my $key (@redundantComponents) + { + #print $key."\n"; + if (not exists $redundantComponentsHash{$key}) + { + $redundantComponentsHash{$key} = 1; + } + } + foreach my $line () + { + if ($line =~ /\A([^\#,].+?),/) + { + my $component = lc($1); + $component =~ s/\s+//g; + $component =~ s/\t+//g; + + if ((not exists $redundantComponentsHash{$component}) || + ($autoclean == 0)) + { + #print "Adding $line in $cleanexpTable\n"; + print OUTPUT $line; + } + } + else + { + print OUTPUT $line; + } + } + + #Warning: This sets the position in INPUT to the beginning of the file! + my $curPos = tell(INPUT); + seek(INPUT, 0,0); + my $firstLine = ; + my @cells = split /,/, $firstLine; + my $numOfKeys = scalar(@cells) -1; + #restore the position in INPUT + seek (INPUT, $curPos,0); + + #Now add the missing components + if (((keys %mrpHashForProduct)> 0) && ($autoadd == 1)) + { + print OUTPUT "\n\n\#Automatically added componments - NEED CHECKING!\n"; + print "********** Adding missing components **********\n"; + + foreach my $missingComponent (sort keys %mrpHashForProduct) + { + my $categoriesString; + my $counter = 0; + for ($counter = 0; $counter < $numOfKeys; $counter++) + { + $categoriesString = $categoriesString."D E F G,"; + } + my $string = $missingComponent.",".$categoriesString; + + #remove the extra ',' from the string + chop($string); + print OUTPUT $string."\n"; + } + } + print "Closing files\n"; + close(INPUT); + close (OUTPUT); +} + +# Send Email +sub SendEmail +{ + my ($subject, @body) = @_; + my (@message); + + #return 1; # Debug to stop email sending + + push @message,"From: $ENV{COMPUTERNAME}\n"; + push @message,"To: $notification_address\n"; + push @message,"Subject: $subject\n"; + push @message,"\n"; + push @message,@body; + + my $smtp = Net::SMTP->new('lonsmtp.intra', Hello => $ENV{COMPUTERNAME}, Debug => 0); + $smtp->mail(); + $smtp->to($notification_address); + + $smtp->data(@message) or die "ERROR: Sending message because $!"; + $smtp->quit; + +} + +sub main +{ + + GetOptions('help|?' => \$help, 'man' =>\$man, 'remove' =>\$autoclean, + 'add' => \$autoadd, 'e' => \$email) or pod2usage(-verbose => 2); + pod2usage(-verbose => 1) if $help == 1; + pod2usage(-verbose => 2) if $man == 1; + + if ($#ARGV < 0) + { + pod2usage(-verbose => 0); + } + + print "******** $ARGV[0] ********\n"; + my $prod = shift @ARGV; + + my $isTestBuild = $ENV{'PublishLocation'}; + + if ($isTestBuild =~ m/Test/i) + + { + + $email = 0 ; + + print "\nThis is a test build, no need to export\n"; + + exit 1; + + } + + + if (not exists $exportTable{$prod}) + { + print "ERROR: Product is invalid\n"; + print "Aborting...\n"; + exit; + + } + + + getExportTableComponents($prod); + getGtAndTvFiles($prod); + compareTables($prod); + if (($autoclean == 1) || ($autoadd == 1) ) + { + autoclean($prod); + } +} + +main(); + +=pod + +=head1 NAME + +check_tables.pl - Check the export tables for a product against the components that are in the product. + +=head1 SYNOPSIS + +check_tables.pl [options] + + Options: + -help brief help message + -man full documentation + -remove Automatically remove redundant components. See below for details. + -add Automatically add missing components. See below for details. + -e Sends a notification email if a component is missing from export table. + +=head1 OPTIONS + +=over 8 + +=item B<-help> + +Prints a brief help message and exits + +=item B<-man> + +Prints the manual page and exists + +=item B<-remove> + +Create a clean version of the export table by removing the redundant entries. +The clean table will be placed in the directory where the tool was run from +and will have the same name as the export table in perforce. You will need to +copy it to where you have your Perforce changes mapped in your client. + +=item B<-add> + +The same as -remove but will automatically add the missing components. The +componenets are added with categories D E F and G. + +=item B<-e> + +Sends a notification email to SysBuildSupport@Symbian.com if any components +are missing from the export table. + +=back + +=head1 DESCRIPTION + +B will take a product as an argument and will check the +export table for that product for consistency. It will report any +redundant entries in the export table and also any components that are +missing. It will also report any duplicate entries in the export table +itself. If no problems are found it will report that the tables are +up to date. + +=head1 VERSION + +$Id: //SSS/release/sf/tb92/os/buildtools/bldsystemtools/commonbldutils/check_tables.pl#1 $ +$Change: 1751173 $ $DateTime: 2009/12/19 09:14:39 $ + +=cut