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