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