bldsystemtools/commonbldutils/check_tables.pl
changeset 0 83f4b4db085c
child 2 99082257a271
equal deleted inserted replaced
-1:000000000000 0:83f4b4db085c
       
     1 #!Perl -w
       
     2 
       
     3 use strict;
       
     4 use Pod::Usage;
       
     5 use Getopt::Long;
       
     6 use FindBin;
       
     7 use FileHandle;
       
     8 use Net::SMTP;
       
     9 
       
    10 #--------------------------- GLOBAL VARIABLES ---------------------------#
       
    11 
       
    12 my $startDir = $FindBin::Bin;
       
    13 my %componentList; 		#This has the components from the export table.
       
    14 my @redundantComponents; #This is used by 2 methods. One populates it and 
       
    15 						 #the other reads it to remove the redundant 
       
    16 						 #components from the export table. 
       
    17 
       
    18 # The location of the export tables
       
    19 my $srcDir = $ENV{'SourceDir'};
       
    20 my $platform = $ENV{'Platform'};
       
    21 my $exportTableLocation =  "$srcDir\\os\\deviceplatformrelease\\symbianosbld\\productionbldcbrconfig\\"; 
       
    22   
       
    23  
       
    24 my $help = 0;
       
    25 my $man = 0;
       
    26 my $autoclean = 0;
       
    27 my $autoadd = 0;
       
    28 my $email = 0;
       
    29 
       
    30 my @report;
       
    31 my ($notification_address) = 'SysBuildSupport@symbian.com';
       
    32 my $message;
       
    33 
       
    34 # This has the components from the gt and tv components.txt
       
    35 # We need to manually put into the hash the following because these
       
    36 # are added by the release tools and are not explicitly mentioned in
       
    37 # the GTComponents.txt or TechviewComponents.txt
       
    38 my %mrpHashForProduct=(
       
    39 	"gt_techview_baseline" => 1,
       
    40 	"gt_only_baseline" => 1,
       
    41 	"gt_overwritten"=> 1,
       
    42 	"unresolved" => 1
       
    43 	);  
       
    44 
       
    45 # Just specify the export tables for each product
       
    46 my %exportTable = (
       
    47 		"8.0a" => "AutoCBR_Tornado_test_export.csv",
       
    48 		"8.1a" => "AutoCBR_8.1a_test_export.csv",
       
    49 		"8.0b" => "AutoCBR_Zephyr_test_export.csv",
       
    50 		"8.1b" => "AutoCBR_8.1b_test_export.csv",
       
    51 		"9.0"  => "AutoCBR_9.0_test_export.csv",
       
    52 		"9.1"  => "AutoCBR_9.1_test_export.csv",
       
    53 		"9.2" => "AutoCBR_9.2_test_export.csv",
       
    54 		"9.3" => "AutoCBR_9.3_test_export.csv",
       
    55 		"Intulo" => "AutoCBR_Intulo_test_export.csv",
       
    56 		"Future" => "AutoCBR_Future_test_export.csv",
       
    57 		"9.4" => "AutoCBR_9.4_test_export.csv",
       
    58 		"9.5" => "AutoCBR_9.5_test_export.csv",
       
    59 		"9.6" => "AutoCBR_9.6_test_export.csv",
       
    60 		"tb92" => "AutoCBR_tb92_test_export.csv",
       
    61 		"tb92sf" => "AutoCBR_tb92sf_test_export.csv",
       
    62                 "tb101sf" => "AutoCBR_tb101sf_test_export.csv"
       
    63 		);
       
    64 
       
    65 my %componentFiles = (
       
    66 		"8.0a" => {"gtonly" => $exportTableLocation."8.0a\\gtcomponents.txt",
       
    67 				   "tv" => $exportTableLocation."8.0a\\techviewcomponents.txt"},		
       
    68 		"8.0b" => {"gtonly" => $exportTableLocation."8.0a\\gtcomponents.txt",
       
    69 				   "tv" => $exportTableLocation."8.0a\\techviewcomponents.txt"},		
       
    70 		"8.1a" => {"gtonly" => $exportTableLocation."8.1a\\gtcomponents.txt",
       
    71 				   "tv" => $exportTableLocation."8.1a\\techviewcomponents.txt"},
       
    72 		"8.1b" => {"gtonly" => $exportTableLocation."8.1b\\gtcomponents.txt",
       
    73 				   "tv" => $exportTableLocation."8.1b\\techviewcomponents.txt"},
       
    74 		"9.0"  => {"gtonly" => $exportTableLocation."9.0\\gtcomponents.txt",
       
    75 				   "tv" => $exportTableLocation."9.0\\techviewcomponents.txt"},
       
    76 		"9.1"  => {"gtonly" => $exportTableLocation."9.1\\gtcomponents.txt",
       
    77 				   "tv" => $exportTableLocation."9.1\\techviewcomponents.txt"},
       
    78 		"9.2"  => {"gtonly" => $exportTableLocation."9.2\\gtcomponents.txt",
       
    79 				   "tv" => $exportTableLocation."9.2\\techviewcomponents.txt"},
       
    80 		"9.3"  => {"gtonly" => $exportTableLocation."9.3\\gtcomponents.txt",
       
    81 				   "tv" => $exportTableLocation."9.3\\techviewcomponents.txt"},		
       
    82 		"Intulo"  => {"gtonly" => $exportTableLocation."Intulo\\gtcomponents.txt",
       
    83 				   "tv" => $exportTableLocation."Intulo\\techviewcomponents.txt"},
       
    84 		"Future"  => {"gtonly" => $exportTableLocation."Future\\gtcomponents.txt",
       
    85 				   "tv" => $exportTableLocation."Future\\techviewcomponents.txt"},
       
    86 		"9.4"  => {"gtonly" => $exportTableLocation."9.4\\gtcomponents.txt",
       
    87 				   "tv" => $exportTableLocation."9.4\\techviewcomponents.txt"},
       
    88 		"9.5"  => {"gtonly" => $exportTableLocation."9.5\\gtcomponents.txt",
       
    89 				   "tv" => $exportTableLocation."9.5\\techviewcomponents.txt"},
       
    90 		"9.6"  => {"gtonly" => $exportTableLocation."9.6\\gtcomponents.txt",
       
    91 				   "tv" => $exportTableLocation."9.6\\techviewcomponents.txt"},
       
    92 		"tb92"  => {"gtonly" => $exportTableLocation."tb92\\gtcomponents.txt",
       
    93 				   "tv" => $exportTableLocation."tb92\\techviewcomponents.txt"},
       
    94 		"tb92sf"  => {"gtonly" => $exportTableLocation."tb92sf\\gtcomponents.txt",
       
    95 				   "tv" => $exportTableLocation."tb92sf\\techviewcomponents.txt"},
       
    96                 "tb101sf"  => {"gtonly" => $exportTableLocation."tb101sf\\gtcomponents.txt",
       
    97 				   "tv" => $exportTableLocation."tb101sf\\techviewcomponents.txt"}
       
    98 
       
    99 
       
   100 	);
       
   101 
       
   102  
       
   103 #------------------------ END OF GLOBAL VARIABLES -----------------------#
       
   104 
       
   105 
       
   106 # Utility function to print the keys of a hash ref (passed in).
       
   107 sub printHash
       
   108 {
       
   109 	my $hashRef = shift;
       
   110 	
       
   111 	foreach my $line(sort keys %{$hashRef})
       
   112 	{
       
   113 		push @report, $line."\n";
       
   114 		print $line."\n";
       
   115 	}
       
   116 }
       
   117 
       
   118 
       
   119 
       
   120 # Compare the components in the export table against
       
   121 # the components in the gt and tv components.txt files.
       
   122 sub compareTables
       
   123 {
       
   124 	my $product = shift;
       
   125 	
       
   126 	my $dirty = 0;
       
   127 	foreach my $key (sort keys %componentList)
       
   128 	{
       
   129 		if(exists $mrpHashForProduct{$key})
       
   130 		{
       
   131 			delete $mrpHashForProduct{$key};
       
   132 		}
       
   133 		else
       
   134 		{
       
   135 			push @redundantComponents, $key;
       
   136 		}
       
   137 	}
       
   138 	if (scalar (@redundantComponents) != 0)
       
   139 	{
       
   140 		$dirty =1;
       
   141 		$message = "\n*** The following components can be removed from $exportTable{$product}:\n\n";
       
   142 		print $message;
       
   143 		foreach my $line(@redundantComponents)
       
   144 		{
       
   145 			print $line."\n";
       
   146 		}
       
   147 	}
       
   148 	
       
   149 	if (scalar keys %mrpHashForProduct != 0)
       
   150 	{
       
   151 		$dirty = 1;
       
   152 		$message = "\n*** The following components are missing from $exportTable{$product}:\n\n";
       
   153 		push @report, $message;
       
   154 		print $message;
       
   155 		printHash(\%mrpHashForProduct);
       
   156 		
       
   157 		if ($email == 1)
       
   158 		{
       
   159 			&SendEmail("WARNING: For Symbian_OS_v$product: $exportTable{$product} is not up to date\n ",@report);
       
   160 		}
       
   161 	}
       
   162 	
       
   163 	if ($dirty == 0)
       
   164 	{
       
   165 		print "$exportTable{$product} is up to date\n";
       
   166 	}
       
   167 }
       
   168 # Get the components that are listed in the export table for the 
       
   169 # product. 
       
   170 
       
   171 sub getExportTableComponents
       
   172 {
       
   173 
       
   174 	my $product = shift;
       
   175 	my $expTable = $exportTableLocation."$product\\".$exportTable{$product};
       
   176 	
       
   177 	open(EXP_TABLE,"<$expTable") or die("Cannot open export table:\n$expTable");
       
   178 	
       
   179 	foreach my $line (<EXP_TABLE>)
       
   180 	{
       
   181 		if ($line =~ /\A([^\#,].+?),/)  #Capture the component name. Ignore '#' or ',' if at beginning of line
       
   182 		{
       
   183 			$line = lc($1);
       
   184 			$line =~ s/\s+//g;
       
   185 			$line =~ s/\t+//g;
       
   186 			
       
   187 			if (not exists $componentList{$line})
       
   188 			{
       
   189 				$componentList{$line} = 1;
       
   190 			}
       
   191 			else 
       
   192 			{
       
   193 				print "Duplicate in export table: $line\n";
       
   194 			}
       
   195 		}
       
   196 	}
       
   197 	close EXP_TABLE;
       
   198 }
       
   199 
       
   200 # Get the components from the gt and techview components.txt
       
   201 sub getComps
       
   202 {
       
   203 	my $tvfile = shift;
       
   204 	my $product = shift;
       
   205 	my $rv = shift;
       
   206 	 
       
   207 	my @mrpContents = split /\n/, $rv;
       
   208 	
       
   209 	foreach my $componentsLine (@mrpContents)
       
   210 	{
       
   211 		my $component = lc((split /[\s\t]/, $componentsLine)[0]);
       
   212 		if (not exists $mrpHashForProduct{$component})
       
   213 		{
       
   214 			$mrpHashForProduct{$component} =1;
       
   215 		}
       
   216 		else
       
   217 		{
       
   218 			print "Duplicate in gt/tv component: $component \n";
       
   219 		}
       
   220 	}
       
   221 	undef @mrpContents;
       
   222 	
       
   223 	#We make the assumption that the techviewcomponents.txt is 
       
   224 	#in the same location as the gtcomponents.txt for a given 
       
   225 	#product.
       
   226 	open(TXT1, "<$tvfile") || die("Failed to find the components file for product $product"); 
       
   227 	undef $/;
       
   228 	$rv = <TXT1>;
       
   229 	close(TXT1);
       
   230 
       
   231 	@mrpContents = split /\n/, $rv;
       
   232 	foreach my $componentsLine (@mrpContents)
       
   233 	{
       
   234 		my $component = lc((split /[\s\t]/, $componentsLine)[0]);
       
   235 		if (not exists $mrpHashForProduct{$component})
       
   236 		{
       
   237 			$mrpHashForProduct{$component} =1;
       
   238 		}
       
   239 		else
       
   240 		{
       
   241 			print "Duplicate in gt/tv component: $component \n";
       
   242 		}
       
   243 	}
       
   244 }
       
   245 
       
   246 # Get the location where the gt and techview components.txt 
       
   247 # are in. Get the contents of the gtcomponents.txt. The 
       
   248 # contents of the techviewcomponents.txt are gotten in getComps
       
   249 # function. 
       
   250 sub getGtAndTvFiles
       
   251 {
       
   252 	my $product = shift; 
       
   253 	
       
   254 	my $rv;
       
   255 	my $gtfilename = $componentFiles{$product}->{"gtonly"};
       
   256 	my $tvfilename = $componentFiles{$product}->{"tv"};
       
   257 	
       
   258 	open(TXT2, "<$gtfilename") || die("Failed to find the components file for product $product");
       
   259 	undef $/;
       
   260 	$rv = <TXT2>;
       
   261 	close(TXT2);
       
   262 	
       
   263 	getComps($tvfilename, $product, $rv);
       
   264 	
       
   265 # 	if ($rv !~ /no such file/)
       
   266 # 	{
       
   267 # 		my $tvfilename = "//EPOC/master/beech/product/tools/makecbr/files/$product/techviewcomponents.txt";
       
   268 # 		getComps($tvfilename, $product, $rv);
       
   269 # 		return;
       
   270 # 	}	
       
   271 # 	
       
   272 # 	$gtfilename = "//EPOC/master/os/deviceplatformrelease/symbianosbld/productionbldcbrconfig/$product/gtcomponents.txt";
       
   273 # 	$rv =  `p4 print -q $gtfilename 2>&1`;
       
   274 # 	
       
   275 # 	if ($rv !~ /no such file/)
       
   276 # 	{
       
   277 # 		my $tvfilename = "//EPOC/master/os/deviceplatformrelease/symbianosbld/productionbldcbrconfig/$product/techviewcomponents.txt";
       
   278 # 		getComps($tvfilename, $product, $rv);
       
   279 # 		return;
       
   280 # 	}
       
   281 #	die("Failed to find the Components file for product $product");
       
   282 }
       
   283 
       
   284 sub autoclean ($)
       
   285 {
       
   286 	my $product = shift; 
       
   287 	my $expTable = $exportTableLocation."$product\\".$exportTable{$product};
       
   288 	my %redundantComponentsHash;
       
   289 		
       
   290 	my $cleanexpTable = $exportTable{$product};
       
   291 	$cleanexpTable =~ s/\.csv//;
       
   292 	$cleanexpTable = $startDir."\\"."${cleanexpTable}.csv"; 
       
   293     
       
   294     if ($autoclean == 1)
       
   295     {
       
   296         print "********** Removing redundant components **********\n";
       
   297     }
       
   298 	#open the export table
       
   299 	open(INPUT, "<$expTable") or die ("Could not open $expTable for read\n");
       
   300 	
       
   301 	#create the clean table
       
   302 	open(OUTPUT, ">$cleanexpTable") or die ("Could not create $cleanexpTable\n");
       
   303 	
       
   304 	foreach my $key (@redundantComponents)
       
   305 	{
       
   306 		#print $key."\n";
       
   307 		if (not exists $redundantComponentsHash{$key})
       
   308 		{
       
   309 			 $redundantComponentsHash{$key} = 1;
       
   310 		}
       
   311 	}
       
   312 	foreach my $line (<INPUT>)
       
   313 	{
       
   314 		if ($line =~ /\A([^\#,].+?),/)
       
   315 		{
       
   316 			my $component = lc($1);
       
   317 			$component =~ s/\s+//g;
       
   318 			$component =~ s/\t+//g;
       
   319 			
       
   320 			if ((not exists $redundantComponentsHash{$component}) || 
       
   321 			    ($autoclean == 0))
       
   322 			{
       
   323 				#print "Adding $line in $cleanexpTable\n";
       
   324 				print OUTPUT $line; 
       
   325 			}
       
   326 		}
       
   327 		else 
       
   328 		{
       
   329 			print OUTPUT $line; 
       
   330 		}
       
   331 	}
       
   332 	
       
   333 	#Warning: This sets the position in INPUT to the beginning of the file!
       
   334 	my $curPos = tell(INPUT);
       
   335 	seek(INPUT, 0,0);
       
   336     my $firstLine = <INPUT>;
       
   337     my @cells = split /,/, $firstLine;
       
   338     my $numOfKeys = scalar(@cells) -1;
       
   339 	#restore the position in INPUT
       
   340 	seek (INPUT, $curPos,0);
       
   341 	
       
   342 	#Now add the missing components
       
   343 	if (((keys %mrpHashForProduct)> 0) && ($autoadd == 1))
       
   344 	{
       
   345 	   print OUTPUT "\n\n\#Automatically added componments - NEED CHECKING!\n";
       
   346 	   print "**********   Adding missing components   **********\n";
       
   347 	
       
   348        foreach my $missingComponent (sort keys %mrpHashForProduct)
       
   349        {
       
   350     	   my $categoriesString;
       
   351     	   my $counter = 0;
       
   352     	   for ($counter = 0; $counter < $numOfKeys; $counter++)
       
   353     	   {
       
   354     	       $categoriesString = $categoriesString."D E F G,";
       
   355     	   }
       
   356     	   my $string = $missingComponent.",".$categoriesString;
       
   357     	   
       
   358     	   #remove the extra ',' from the string
       
   359     	   chop($string);
       
   360     	   print OUTPUT $string."\n";
       
   361        }
       
   362 	}
       
   363 	print "Closing files\n";
       
   364 	close(INPUT);
       
   365 	close (OUTPUT);
       
   366 }
       
   367 
       
   368 # Send Email
       
   369 sub SendEmail
       
   370 {
       
   371   my ($subject, @body) = @_;
       
   372   my (@message);
       
   373   
       
   374   #return 1; # Debug to stop email sending
       
   375   
       
   376   push @message,"From: $ENV{COMPUTERNAME}\n";
       
   377   push @message,"To: $notification_address\n";
       
   378   push @message,"Subject: $subject\n";
       
   379   push @message,"\n";
       
   380   push @message,@body;
       
   381   
       
   382   my $smtp = Net::SMTP->new('lonsmtp.intra', Hello => $ENV{COMPUTERNAME}, Debug   => 0);
       
   383   $smtp->mail();
       
   384   $smtp->to($notification_address);
       
   385   
       
   386   $smtp->data(@message) or die "ERROR: Sending message because $!";
       
   387   $smtp->quit;
       
   388 
       
   389 }
       
   390 
       
   391 sub main
       
   392 {
       
   393 
       
   394 	GetOptions('help|?' => \$help, 'man' =>\$man, 'remove' =>\$autoclean,
       
   395 	           'add' => \$autoadd, 'e' => \$email) or pod2usage(-verbose => 2);
       
   396 	pod2usage(-verbose => 1) if $help == 1;
       
   397 	pod2usage(-verbose => 2) if $man == 1;
       
   398 	
       
   399 	if ($#ARGV < 0)
       
   400 	{
       
   401 		pod2usage(-verbose => 0);
       
   402 	}
       
   403 	
       
   404 	print "******** $ARGV[0] ********\n";
       
   405 	my $prod = shift @ARGV;
       
   406 
       
   407         my $isTestBuild = $ENV{'PublishLocation'};
       
   408 
       
   409         if ($isTestBuild =~ m/Test/i)
       
   410 
       
   411        {
       
   412    
       
   413          $email = 0 ;
       
   414 
       
   415          print "\nThis is a test build, no need to export\n";
       
   416 
       
   417          exit 1;
       
   418 
       
   419        }
       
   420 
       
   421       
       
   422 	if (not exists $exportTable{$prod})
       
   423 	{
       
   424 		print "ERROR: Product is invalid\n";
       
   425 		print "Aborting...\n";
       
   426 		exit;
       
   427        
       
   428 	}
       
   429 
       
   430 	
       
   431 	getExportTableComponents($prod);
       
   432 	getGtAndTvFiles($prod);
       
   433 	compareTables($prod);
       
   434 	if (($autoclean == 1) || ($autoadd == 1) )
       
   435 	{
       
   436 		autoclean($prod);
       
   437 	}
       
   438 }
       
   439 
       
   440 main();
       
   441 
       
   442 =pod
       
   443 
       
   444 =head1 NAME
       
   445 
       
   446 check_tables.pl - Check the export tables for a product against the components that are in the product.
       
   447 
       
   448 =head1 SYNOPSIS
       
   449 
       
   450 check_tables.pl [options] <product>
       
   451 
       
   452  Options:
       
   453    -help			brief help message
       
   454    -man 			full documentation
       
   455    -remove			Automatically remove redundant components. See below for details.
       
   456    -add             Automatically add missing components. See below for details. 
       
   457    -e				Sends a notification email if a component is missing from export table.
       
   458 
       
   459 =head1 OPTIONS
       
   460 
       
   461 =over 8
       
   462 
       
   463 =item B<-help>
       
   464 
       
   465 Prints a brief help message and exits
       
   466 
       
   467 =item B<-man>
       
   468 
       
   469 Prints the manual page and exists
       
   470 
       
   471 =item B<-remove>
       
   472 
       
   473 Create a clean version of the export table by removing the redundant entries.
       
   474 The clean table will be placed in the directory where the tool was run from 
       
   475 and will have the same name as the export table in perforce. You will need to  
       
   476 copy it to where you have your Perforce changes mapped in your client. 
       
   477 
       
   478 =item B<-add>
       
   479 
       
   480 The same as -remove but will automatically add the missing components. The 
       
   481 componenets are added with categories D E F and G. 
       
   482 
       
   483 =item B<-e>
       
   484 
       
   485 Sends a notification email to SysBuildSupport@Symbian.com if any components
       
   486 are missing from the export table.
       
   487 
       
   488 =back
       
   489 
       
   490 =head1 DESCRIPTION
       
   491 
       
   492 B<This program> will take a product as an argument and will check the 
       
   493 export table for that product for consistency. It will report any 
       
   494 redundant entries in the export table and also any components that are
       
   495 missing. It will also report any duplicate entries in the export table
       
   496 itself. If no problems are found it will report that the tables are 
       
   497 up to date. 
       
   498 
       
   499 =head1 VERSION
       
   500 
       
   501 $Id: //SSS/release/sf/tb92/os/buildtools/bldsystemtools/commonbldutils/check_tables.pl#1 $
       
   502 $Change: 1751173 $  $DateTime: 2009/12/19 09:14:39 $
       
   503 
       
   504 =cut