as released as part of build91
[pspp] / results2html
1 #! /usr/bin/env perl
2
3 use strict;
4 use warnings;
5
6 use File::Spec;
7 use HTML::Entities;
8 use URI::Escape;
9
10 my $gitweb_url = 'http://benpfaff.org/cgi-bin/gitweb.cgi?p=pspp;a=blob;f=[FILE];hb=[BRANCH]#l[LINE]';
11
12 open (LOG, '<', "LOG");
13 open (LOG_HTML, '>', "log.html");
14
15 print LOG_HTML <<EOF;
16 <html>
17 <head>
18   <link rel="stylesheet" href="build.css">
19 </head>
20 <body>
21 EOF
22 print LOG_HTML "<pre>";
23
24 sub read_vars {
25     my ($file) = @_;
26     my %vars = ();
27     if (open (VARS, "<", $file)) {
28         while (<VARS>) {
29             chomp;
30             my ($key, $value) = /^([^=]+)=(.*)/ or next;
31             $vars{$key} = $value;
32         }
33         close (VARS);
34     }
35     return %vars;
36 }
37 my (%vars) = read_vars ('VARS');
38
39 my (@products);
40 my (@steps);
41 my ($result) = "failure";
42 my (%dist_files);
43 my ($dist_dir);
44 my @dirstack;
45 while (<LOG>) {
46     my $ln = $.;
47     chomp;
48
49     if (/Entering directory `(.*)'$/) {
50         push (@dirstack, $1);
51     } elsif (/Leaving directory `(.*)'$/) {
52         pop (@dirstack);
53     }
54
55     my $log_class;
56     if (my ($title) = /^## (.*) ##$/) {
57         $log_class = "step";
58         if (my ($name, $product) = $title =~ /^Saving(?:\s+([^:]*):)?\s+(.*)$/) {
59             my $href = "$product/summary.html";
60             $href = $product if ! -e $href;
61
62             my (%p);
63             $p{NAME} = $name if defined ($name);
64             $p{PRODUCT} = $product;
65             $p{HREF} = $href;
66             $p{LN} = $ln;
67             push (@products, \%p);
68             push (@{$steps[$#steps]{CHILDREN}}, \%p);
69
70             if (defined ($name) && $name eq 'source distribution') {
71                 open (DIST, '-|', "zcat $product | tar tf -");
72                 while (my $line = <DIST>) {
73                     chomp $line;
74                     $line =~ s%^([./])*%%; # Trim leading ./
75                     $dist_files{$line} = 1;
76                     if (!defined ($dist_dir)) {
77                         $dist_dir = (split ('/', $line))[0];
78                     }
79                 }
80                 close (DIST);
81             }
82         } elsif ($title eq 'Success') {
83             $result = 'success';
84         } elsif ($title !~ /^-+$/) {
85             my (%s);
86             $s{TITLE} = $title;
87             $s{LN} = $ln;
88             push (@steps, \%s);
89         }
90     } else {
91         my $diagnostic;
92         $diagnostic = "error" if /error:/i || /FAILED/;
93         $diagnostic = "warning" if /warning:/i;
94         if ($diagnostic) {
95             my (%d);
96             $d{DIAGNOSTIC} = $diagnostic;
97             $d{MESSAGE} = $_;
98             $d{LN} = $ln;
99
100             if (@dirstack && defined ($dist_dir)
101                 && (my ($match, $file, $line) = /^(([^\s:]+):(\d+):)/)) {
102                 $file = File::Spec->rel2abs ($file, $dirstack[$#dirstack]);
103                 my (@path) = grep ($_ ne '' && $_ ne '.', split ('/', $file));
104                 for (my $i = 1; $i <= $#path; ) {
105                     if ($path[$i] eq '..') {
106                         splice (@path, $i - 1, 2);
107                         $i-- if $i > 1;
108                     } else {
109                         $i++;
110                     }
111                 }
112
113                 for (my $i = $#path; $i >= 0; $i--) {
114                     if ($path[$i] eq $dist_dir) {
115                         my $dist_file = join ('/', @path[$i..$#path]);
116                         if (exists ($dist_files{$dist_file})) {
117                             $d{MATCH} = length ($match);
118                             $d{LINE} = $line;
119                             $d{FILE} = $dist_file;
120                         }
121                         last;
122                     }
123                 }
124             }
125             push (@{$steps[$#steps]{CHILDREN}}, \%d);
126         }
127     }
128     printf LOG_HTML "<a name=\"%d\"><tt>%4d</tt></a>  ", $ln, $ln;
129     if (defined ($log_class)) {
130         print LOG_HTML "<span class=\"$log_class\">", encode_entities ($_), "</span>\n";
131     } else {
132         print LOG_HTML encode_entities ($_), "\n";
133     }
134 }
135
136 open (INDEX, '>','summary.html');
137
138 print INDEX <<EOF;
139 <html>
140 <head>
141   <link rel="stylesheet" href="build.css">
142 </head>
143 <body>
144 EOF
145
146 print INDEX "<h1>Build ", $vars{"BUILD_NUMBER"}, ": $result</h1>\n";
147
148 print INDEX "<h2>Build Properties</h2>\n";
149 print INDEX "<table>\n";
150 print INDEX "<tr><th>Name</th><th>Value</th></tr>\n";
151 foreach my $key (sort (keys (%vars))) {
152     print INDEX "<tr>";
153     print INDEX "<td>", encode_entities ($key), "</td>";
154     print INDEX "<td>", encode_entities ($vars{$key}), "</td>";
155     print INDEX "</tr>\n";
156 }
157 print INDEX "</table>\n";
158
159 print INDEX "<h2>Build Products</h2>\n";
160 print INDEX "<ul>\n";
161 foreach my $p (@products) {
162     print INDEX "<li>";
163     print INDEX encode_entities ($p->{NAME}), ": " if defined ($p->{NAME});
164     print INDEX "<a href=\"", encode_entities ($p->{HREF}), "\">";
165     print INDEX encode_entities ($p->{PRODUCT});
166     print INDEX "</a></li>\n";
167 }
168 print INDEX "</ul>\n";
169
170 sub log_link {
171     my ($ln) = @_;
172     return "<small><a href=\"log.html#$ln\">(log)</a></small>";
173 }
174
175 print INDEX "<h2>Build Summary</h2>\n";
176 print INDEX "<ol>\n";
177 foreach my $s (@steps) {
178     print INDEX "<li>", encode_entities ($s->{TITLE});
179     print INDEX " ", log_link ($s->{LN});
180     foreach my $c (@{$s->{CHILDREN}}) {
181         if (defined ($c->{DIAGNOSTIC})) {
182             print INDEX "<p class=\"$c->{DIAGNOSTIC}\">";
183             if (defined ($c->{MATCH})) {
184                 my $href = $gitweb_url;
185                 $href =~ s/\[FILE\]/uri_escape ($c->{FILE})/ge;
186                 $href =~ s/\[LINE\]/$c->{LINE}/g;
187                 $href =~ s/\[BRANCH\]/uri_escape ($vars{'dist_commit'})/e;
188
189                 print INDEX '<a href="', encode_entities ($href), '">';
190                 print INDEX encode_entities (substr ($c->{MESSAGE},
191                                                      0, $c->{MATCH}));
192                 print INDEX '</a>';
193                 print INDEX encode_entities (substr ($c->{MESSAGE},
194                                                      $c->{MATCH}));
195             } else {
196                 print INDEX encode_entities ($c->{MESSAGE});
197             }
198             print INDEX " ", log_link ($c->{LN});
199             print INDEX "</p>\n";
200         } else {
201             print INDEX "<p>&rarr; <a href=\"", encode_entities ($c->{HREF}), "\">";
202             print INDEX encode_entities ($c->{PRODUCT});
203             print INDEX "</a> ";
204             print INDEX log_link ($c->{LN});
205             print INDEX "</p>\n";
206         }
207     }
208     print INDEX "</li>\n";
209 }
210 print INDEX "</ol>\n";
211
212 print INDEX <<EOF;
213 </body>
214 </html>
215 EOF
216
217 print LOG_HTML <<EOF;
218 </pre>
219 </body>
220 </html>
221 EOF
222
223 open (HTACCESS, '>', '.htaccess');
224 print HTACCESS <<EOF;
225 DirectorySlash off
226 EOF
227
228 open (CSS, '>', "build.css");
229 print CSS <<EOF;
230 body {
231         background: white;
232         color: black;
233         padding: 0em 3em 0em 3em;
234         margin: 0
235 }
236 body>p {
237         margin: 0pt 0pt 0pt 0em
238 }
239 body>p + p {
240         text-indent: 1.5em;
241 }
242 H1 {
243         font-size: 150%;
244         margin-left: -1.33em
245 }
246 H2 {
247         font-size: 125%;
248         font-weight: bold;
249         margin-left: -.8em
250 }
251 H3 {
252         font-size: 100%;
253         font-weight: bold;
254         margin-left: -.5em }
255 H4 {
256         font-size: 100%;
257         margin-left: 0em
258 }
259 H1, H2, H3, H4, H5, H6 {
260         font-family: sans-serif;
261         color: blue
262 }
263 html {
264         margin: 0
265 }
266
267 a:link {
268         color: blue;
269         text-decoration: none;
270 }
271 a:visited {
272         color: gray;
273         text-decoration: none;
274 }
275 a:active {
276         color: black;
277         text-decoration: none;
278 }
279 a:hover {
280         text-decoration: underline
281 }
282
283 ol>li>p {
284         margin-top: 0;
285         margin-bottom: 0
286 }
287 .step {
288         font-weight: bold
289 }
290 .warning {
291         background: yellow
292 }
293 .error {
294         background: orange
295 }
296 EOF