common/tools/brag/yarpToBRAG.pl
changeset 649 4468add5d834
child 650 b4c5f01c1ab7
equal deleted inserted replaced
648:5d343f062b11 649:4468add5d834
       
     1 #!perl -w
       
     2 #
       
     3 # Copyright (c) 2009 Symbian Foundation Ltd
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Symbian Foundation Ltd - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 # Generate the BRAG-compatible XML summary of the Raptor log from Yarp analysis
       
    16 
       
    17 use strict;
       
    18 
       
    19 use Getopt::Long;
       
    20 use Text::CSV;
       
    21 
       
    22 
       
    23 if (!@ARGV)
       
    24 {
       
    25 	warn "Generate an XML summary of the Raptor build from a Yarp CSV file\n";
       
    26 	warn "Eg: yarpToBRAG.pl aYarpFile.csv [*_yarp.csv ...]\n";
       
    27 	exit(1);
       
    28 }
       
    29 
       
    30 # Start to build structure to be output as XML (same format as XML::Parser would create for us)
       
    31 my $xmlNewline = bless { Text => "\n" }, "Characters";
       
    32 my $buildPhase = bless { name => "Build", Kids => [ $xmlNewline ] }, "phase";
       
    33 my $buildStatus =
       
    34 [
       
    35 	bless
       
    36 	{
       
    37 		Kids =>
       
    38 		[
       
    39 			$xmlNewline,
       
    40 			$buildPhase,
       
    41 			$xmlNewline,
       
    42 		]
       
    43 	}, "buildStatus"
       
    44 ];
       
    45 
       
    46 @ARGV = map { glob $_ } @ARGV;
       
    47 
       
    48 foreach my $yarpCSV (@ARGV)
       
    49 {
       
    50 	# Read Yarp CSV File
       
    51 	unless (open(CSV, $yarpCSV))
       
    52 	{
       
    53 		warn "ERROR: Unable to open $yarpCSV to process. Skipping.\n";
       
    54 		next;
       
    55 	}
       
    56 
       
    57 	my $csv = Text::CSV->new();
       
    58 	my @keys = ();
       
    59 	while (my $line = <CSV>)
       
    60 	{
       
    61 		chomp $line;
       
    62 		
       
    63 		unless ($csv->parse($line))
       
    64 		{
       
    65 			my $err = $csv->error_input();
       
    66 			warn "WARNING: Failed to parse $yarpCSV line $. as CSV '$line': $err  Skipping\n";
       
    67 			next;
       
    68 		}
       
    69 
       
    70 		if (!@keys)
       
    71 		{
       
    72 			@keys = $csv->fields();
       
    73 			next;
       
    74 		}
       
    75 
       
    76 		my @values = $csv->fields();
       
    77 		last unless $values[0];
       
    78 		unless (scalar @values == scalar @keys)
       
    79 		{
       
    80 			warn "WARNING: line does not match expected format at $yarpCSV line $.. Skipping\n";
       
    81 			next;
       
    82 		}
       
    83 		# Populate the hash using a hash slice
       
    84 		my $failure = {};
       
    85 		@{$failure}{@keys} = @values;
       
    86 		$failure->{platform} = lc $failure->{platform};
       
    87 		
       
    88 		# Work out the package
       
    89 		$failure->{package} = $failure->{bldinf};
       
    90 		$failure->{package} =~ s{[A-Z]:}{}i;
       
    91 		$failure->{package} =~ s{^(/sf/.*?/.*?)/.*}{$1}i;
       
    92 		
       
    93 		# Create a more readable error message
       
    94 		my %errorIdToDetail = (
       
    95 			tem => {message => "Failed to process $failure->{source}", severity => "major"},
       
    96 			msvctoolscompile => {message => "Failed to compile $failure->{source}", severity => "minor"},
       
    97 			compile => {message => "Failed to compile $failure->{source}", severity => "minor"},
       
    98 			compile2object => {message => "Failed to compile $failure->{source}", severity => "minor"},
       
    99 			win32compile2object => {message => "Failed to compile $failure->{source}", severity => "minor"},
       
   100 			tools2lib => {message => "Failed to build library $failure->{target}", severity => "minor"},
       
   101 			win32archive => {message => "Failed to build library $failure->{target}", severity => "minor"},
       
   102 			"link" => {message => "Failed to create symbols for $failure->{target}", severity => "minor"},
       
   103 			postlink => {message => "Failed to link $failure->{target}", severity => "minor"},
       
   104 			win32stageonelink => {message => "Failed to link $failure->{target} (stage 1)", severity => "minor"},
       
   105 			win32stagetwolink => {message => "Failed to link $failure->{target}", severity => "minor"},
       
   106 			win32simplelink => {message => "Failed to link $failure->{target}", severity => "minor"},
       
   107 			win32processexports => {message => "Failed to export $failure->{source} to $failure->{target}", severity => "minor"},
       
   108 			tracecompile => {message => "Trace compile failure for $failure->{target}", severity => "unknown"},
       
   109 			extension_makefile => {message => "Failed to process an extension makefile connected to $failure->{bldinf}", severity => "major"},
       
   110 		);
       
   111 #		die $failure->{name} unless exists $errorIdToDetail{$failure->{name}};
       
   112 		my $message = $errorIdToDetail{$failure->{name}}->{message} || "Unknown failure tag '$failure->{name}' ($failure->{source} -> $failure->{target})";
       
   113 		$failure->{severity} = $errorIdToDetail{$failure->{name}}->{severity} || "unknown";
       
   114 
       
   115 		# Look through the steps to see if we already have one to match this platform
       
   116 		my $step;
       
   117 		foreach (@{$buildPhase->{Kids}})
       
   118 		{
       
   119 			next unless ref $_ eq "step";
       
   120 			if ($_->{name} eq $failure->{platform})
       
   121 			{
       
   122 				$step = $_;
       
   123 				last;
       
   124 			}
       
   125 		}
       
   126 		unless ($step)
       
   127 		{
       
   128 			# First item found for this platform - create step entry
       
   129 			$step = bless { name => $failure->{platform}, Kids => [ $xmlNewline ] }, "step";
       
   130 			push @{$buildPhase->{Kids}}, $step, $xmlNewline;
       
   131 			# Also create empty <failures> tags with severities in a sensible order
       
   132 			foreach my $severity (qw{critical major minor})
       
   133 			{
       
   134 				my $failureSet = bless { level => $severity, Kids => [ $xmlNewline ] }, "failures";
       
   135 				push @{$step->{Kids}}, $failureSet, $xmlNewline;
       
   136 			}
       
   137 		}
       
   138 		
       
   139 		# Look through the sets of failures in this step to see if we hve one which matches this severity
       
   140 		my $failureSet;
       
   141 		foreach (@{$step->{Kids}})
       
   142 		{
       
   143 			next unless ref $_ eq "failures";
       
   144 			if ($_->{level} eq $failure->{severity})
       
   145 			{
       
   146 				$failureSet = $_;
       
   147 				last;
       
   148 			}
       
   149 		}
       
   150 		unless ($failureSet)
       
   151 		{
       
   152 			# First item found at this severity - create failures entry
       
   153 			$failureSet = bless { level => $failure->{severity}, Kids => [ $xmlNewline ] }, "failures";
       
   154 			push @{$step->{Kids}}, $failureSet, $xmlNewline;
       
   155 		}
       
   156 		
       
   157 		# Now create the failure itself, and add it to this failure set
       
   158 		my $failureItem = bless {
       
   159 #			href => "",
       
   160 			"package" => $failure->{package},
       
   161 			Kids => [ bless { Text => $message }, "Characters" ],
       
   162 		}, "failure";
       
   163 		push @{$failureSet->{Kids}}, $failureItem, $xmlNewline;
       
   164 	}
       
   165 	close(CSV);
       
   166 }
       
   167 # Print XML
       
   168 print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
       
   169 print "<?xml-stylesheet type='text/xsl' href='brag.xsl'?>\n";
       
   170 printTree($buildStatus->[0]);
       
   171 print "\n";
       
   172 
       
   173 exit(0);
       
   174 
       
   175 sub printTree
       
   176 {
       
   177 	my $tree = shift or die;
       
   178 	die unless ref $tree;
       
   179 
       
   180 	my $tagName = ref $tree;
       
   181 	$tagName =~ s{^main::}{};
       
   182 	if ($tagName eq "Characters")
       
   183 	{
       
   184 		print $tree->{Text};
       
   185 		return;
       
   186 	}
       
   187 	
       
   188 	print "<$tagName";
       
   189 
       
   190 	foreach my $attr (
       
   191 		sort {
       
   192 			my $order = "name level start stop href";
       
   193 			my $ixA = index $order, $a;
       
   194 			my $ixB = index $order, $b;
       
   195 			die "$a $b" if $ixA + $ixB == -2;
       
   196 			$ixA - $ixB;
       
   197 		}
       
   198 		grep {
       
   199 			! ref $tree->{$_}
       
   200 		}
       
   201 		keys %$tree)
       
   202 	{
       
   203 		print " $attr=\"$tree->{$attr}\"";
       
   204 	}
       
   205 
       
   206 	my $children = $tree->{Kids} || [];
       
   207 	if (scalar @$children)
       
   208 	{
       
   209 		print ">";
       
   210 		foreach my $child (@$children)
       
   211 		{
       
   212 			printTree($child);
       
   213 		}
       
   214 		print "</$tagName";
       
   215 	}
       
   216 	else
       
   217 	{
       
   218 		print "/"
       
   219 	}
       
   220 
       
   221 	print ">";
       
   222 }
       
   223