bldsystemtools/commonbldutils/check_tables.pl
changeset 0 83f4b4db085c
child 2 99082257a271
--- /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