--- /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 (<EXP_TABLE>)
+ {
+ 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 = <TXT1>;
+ 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 = <TXT2>;
+ 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 (<INPUT>)
+ {
+ 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 = <INPUT>;
+ 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] <product>
+
+ 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<This program> 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