|
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 # Identifies failures in a log file (as determined by a set of rules) and produces a BRAG XML summary |
|
16 |
|
17 use strict; |
|
18 |
|
19 use Getopt::Long; |
|
20 |
|
21 my $phaseName; |
|
22 my $stepName; |
|
23 my $rulesFile; |
|
24 my $help = 0; |
|
25 GetOptions(( |
|
26 'phase=s' => \$phaseName, |
|
27 'step=s' => \$stepName, |
|
28 'rules=s' => \$rulesFile, |
|
29 'help!' => \$help, |
|
30 )); |
|
31 |
|
32 my $wrongArgs = 0; |
|
33 unless ($help) |
|
34 { |
|
35 $wrongArgs += warn "No phase specified to indicate the phase that the failures fall under\n" unless defined $phaseName; |
|
36 $wrongArgs += warn "No step specified to indicate the step that the failures fall under\n" unless defined $stepName; |
|
37 $wrongArgs += warn "No file of rules specified to interpret the log file\n" unless defined $rulesFile; |
|
38 $wrongArgs += warn "No log files to process\n" unless @ARGV; |
|
39 } |
|
40 if ($help || $wrongArgs) |
|
41 { |
|
42 print <<"EOT"; |
|
43 |
|
44 logToBRAG.pl --phase=prebuild --step=syncsource --rules=syncsourceRules.tsv presync.log [doSync.log ...] > output.xml |
|
45 EOT |
|
46 exit(0 + !$help); |
|
47 } |
|
48 |
|
49 # Start to build structure to be output as XML (same format as XML::Parser would create for us) |
|
50 my $xmlNewline = bless { Text => "\n" }, "Characters"; |
|
51 my $step = bless { |
|
52 name => $stepName, |
|
53 Kids => [ $xmlNewline ] |
|
54 }, "step"; |
|
55 my $phase = bless { |
|
56 name => $phaseName, |
|
57 Kids => [ $xmlNewline, $step, $xmlNewline ] |
|
58 }, "phase"; |
|
59 my $buildStatus = [ bless { |
|
60 Kids => |
|
61 [ |
|
62 $xmlNewline, |
|
63 $phase, |
|
64 $xmlNewline, |
|
65 ] |
|
66 }, "buildStatus"]; |
|
67 |
|
68 # Also create empty <failures> tags with severities in a sensible order |
|
69 # And shortcuts to those items |
|
70 my $severityShortcut = {}; |
|
71 foreach my $severity (qw{critical major minor}) |
|
72 { |
|
73 my $failureSet = bless { level => $severity, Kids => [ $xmlNewline ] }, "failures"; |
|
74 push @{$step->{Kids}}, $failureSet, $xmlNewline; |
|
75 $severityShortcut->{$severity} = $failureSet; |
|
76 } |
|
77 |
|
78 # Read rules file |
|
79 my @rules; |
|
80 open(TSV, $rulesFile) or die "Unable to open rules file '$rulesFile'\n"; |
|
81 while (my $line = <TSV>) |
|
82 { |
|
83 chomp $line; |
|
84 next unless $line; |
|
85 my @terms = split m{\t+}, $line; |
|
86 die "Rules file not formatted as expected at line $.\n" unless scalar @terms == 2; |
|
87 push @rules, { regexp => $terms[0], severity => $terms[1] }; |
|
88 } |
|
89 |
|
90 # Iterate through all the lines of all the files in @ARGV |
|
91 foreach my $line (<>) |
|
92 { |
|
93 chomp $line; |
|
94 foreach my $rule (@rules) |
|
95 { |
|
96 if ($line =~ m[$rule->{regexp}]) |
|
97 { |
|
98 # We found a match |
|
99 my $failure = bless{ Kids => [ bless { Text => $line }, "Characters" ] }, "failure"; |
|
100 # Ensure we have a <failures> tag for this severity |
|
101 if (!exists $severityShortcut->{$rule->{severity}}) |
|
102 { |
|
103 # Create the failure set and add it to the shortcut list too |
|
104 my $failureSet = bless { level => $rule->{severity}, Kids => [ $xmlNewline ] }, "failures"; |
|
105 push @{$step->{Kids}}, $failureSet, $xmlNewline; |
|
106 $severityShortcut->{$rule->{severity}} = $failureSet; |
|
107 } |
|
108 push @{$severityShortcut->{$rule->{severity}}->{Kids}}, $failure, $xmlNewline; |
|
109 # Do not consider any more rules |
|
110 last; |
|
111 } |
|
112 } |
|
113 } |
|
114 |
|
115 # Print XML |
|
116 print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; |
|
117 print "<?xml-stylesheet type='text/xsl' href='brag.xsl'?>\n"; |
|
118 printTree($buildStatus->[0]); |
|
119 print "\n"; |
|
120 |
|
121 exit(0); |
|
122 |
|
123 sub printTree |
|
124 { |
|
125 my $tree = shift or die; |
|
126 die unless ref $tree; |
|
127 |
|
128 my $tagName = ref $tree; |
|
129 $tagName =~ s{^main::}{}; |
|
130 if ($tagName eq "Characters") |
|
131 { |
|
132 print $tree->{Text}; |
|
133 return; |
|
134 } |
|
135 |
|
136 print "<$tagName"; |
|
137 |
|
138 foreach my $attr ( |
|
139 sort { |
|
140 my $order = "name level start stop href"; |
|
141 my $ixA = index $order, $a; |
|
142 my $ixB = index $order, $b; |
|
143 die "$a $b" if $ixA + $ixB == -2; |
|
144 $ixA - $ixB; |
|
145 } |
|
146 grep { |
|
147 ! ref $tree->{$_} |
|
148 } |
|
149 keys %$tree) |
|
150 { |
|
151 print " $attr=\"$tree->{$attr}\""; |
|
152 } |
|
153 |
|
154 my $children = $tree->{Kids} || []; |
|
155 if (scalar @$children) |
|
156 { |
|
157 print ">"; |
|
158 foreach my $child (@$children) |
|
159 { |
|
160 printTree($child); |
|
161 } |
|
162 print "</$tagName"; |
|
163 } |
|
164 else |
|
165 { |
|
166 print "/" |
|
167 } |
|
168 |
|
169 print ">"; |
|
170 } |
|
171 |