Make filter-build-webkit testable using LoadAsModule
[WebKit-https.git] / Tools / Scripts / filter-build-webkit
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
4
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1.  Redistributions of source code must retain the above copyright
9 #     notice, this list of conditions and the following disclaimer.
10 # 2.  Redistributions in binary form must reproduce the above copyright
11 #     notice, this list of conditions and the following disclaimer in the
12 #     documentation and/or other materials provided with the distribution.
13
14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
15 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
21 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25 # Filters the output of build-webkit into a more human-readable format.
26
27 use strict;
28 use warnings;
29
30 use CGI qw(escapeHTML);
31 use File::Basename;
32 use FindBin;
33 use lib $FindBin::Bin;
34 use Getopt::Long;
35 use VCSUtils;
36
37 use constant {
38     STYLE_PLAIN => 0,
39     STYLE_HEADER => 1,
40     STYLE_SUCCESS => 2,
41     STYLE_ALERT => 3,
42
43     HTML_HEADER =><<HTMLHEADER,
44 <html>
45     <head>
46         <title>Build Log</title>
47         <style>
48             body { font-family: Monaco, monospace; font-size: 10px; color: #666; line-height: 1.5em; }
49             h2 { margin: 1.5em 0 0 0; font-size: 1.0em; font-weight: bold; color: blue; }
50             p { margin: 0; padding-left: 1.5em; border-left: 3px solid #fff; }
51             p.alert { border-left-color: red; color: red; margin: 1.5em 0 0 0; }
52             p.alert + p { margin: 1.5em 0 0 0; }
53             p.alert + p.alert { margin: 0; }
54             p.success { color: green; }
55         </style>
56     </head>
57     <body>
58 HTMLHEADER
59
60     HTML_FOOTER =><<HTMLFOOTER,
61     </body>
62 </html>
63 HTMLFOOTER
64 };
65
66 sub printLine($$);
67 sub setLogfileOption($$);
68 sub setOutputFormatOption($$);
69 sub usageAndExit();
70
71 # Defined in VCSUtils.
72 sub possiblyColored($$);
73
74 # Global variables used only in global scope.
75 my $outputPath = "&STDOUT";
76 my $showHelp;
77
78 # Global variables used in global and subroutine scope.
79 our $logUnfilteredOutput;
80 our $outputFormat = "text";
81 our $unfilteredOutputPath = "build.log";
82 our $useColor = -t STDOUT;
83
84 sub usageAndExit()
85 {
86     print STDERR <<__END__;
87 Usage: @{[ basename($0) ]} [options] buildlog1 [buildlog2 ...]
88        build-webkit | @{[ basename($0) ]} [options]
89   -h|--help     Show this help message
90 Output Options:
91   -o|--output   Path for output (default: STDOUT)
92   -f|--format   Output format (default: $outputFormat)
93                   text: Plain text
94                   html: Standalone HTML document
95   --[no-]color  ANSI color output for text (default: on, if -o is STDOUT)
96 Unfiltered Logging Options:
97   -l|--log      Save unfiltered output to file (see --log-file)
98   --logfile     Path to save unfiltered output (implies --log, default: $unfilteredOutputPath)
99 __END__
100     exit 1;
101 }
102
103 my $getOptionsResult = GetOptions(
104     'h|help'                => \$showHelp,
105     'o|output=s'            => \$outputPath,
106     'f|format=s'            => \&setOutputFormatOption,
107     'color!'                => \$useColor,
108     'l|log'                 => \$logUnfilteredOutput,
109     'logfile=s'             => \&setLogfileOption,
110 );
111
112 if (-t STDIN || $showHelp || !$getOptionsResult) {
113     usageAndExit();
114 }
115
116 open(OUTPUT_HANDLE, ">$outputPath") or die "Failed to open $outputPath : $!";
117 if ($logUnfilteredOutput) {
118     open(UNFILTERED_OUTPUT_HANDLE, ">$unfilteredOutputPath") or die "Failed to open $unfilteredOutputPath : $!";
119 }
120
121 print OUTPUT_HANDLE HTML_HEADER if ($outputFormat eq "html");
122
123 my $buildFinished;
124 my $buildFailed = 0;
125 while (my $line = <>) {
126     print UNFILTERED_OUTPUT_HANDLE $line if $logUnfilteredOutput;
127
128     chomp($line);
129
130     next if $line =~ /^\s*$/;
131     next if $line =~ /^Build settings from command line:/;
132     next if $line =~ /make: Nothing to be done for `all'\./;
133     next if $line =~ /^JavaScriptCore\/create_hash_table/;
134     next if $line =~ /JavaScriptCore.framework\/PrivateHeaders\/create_hash_table/;
135     next if $line =~ /^JavaScriptCore\/pcre\/dftables/;
136     next if $line =~ /^Creating hashtable for /;
137     next if $line =~ /^Wrote output to /;
138     next if $line =~ /^(touch|perl|cat|rm -f|bison|flex|python|\/usr\/bin\/g\+\+|gperf|echo|sed|if \[ \-f|WebCore\/generate-export-file) /;
139     next if $line =~ /^UNDOCUMENTED: /;
140     next if $line =~ /libtool.*has no symbols/;
141     next if $line =~ /^# Lower case all the values, as CSS values are case-insensitive$/;
142     next if $line =~ /^if sort /;
143     next if $line =~ /^    /;
144     next if $line =~ /^printf /;
145     next if $line =~ /^offlineasm: Nothing changed/;
146     next if $line =~ /^Showing first/;
147
148     if ($line =~ /^={10}/) {
149         printLine($line, STYLE_SUCCESS);
150         $buildFinished = 1;
151     } elsif ($line =~ /^===/) {
152         printLine($line, STYLE_HEADER);
153     } elsif ($line =~ /Checking Dependencies|Check dependencies/) {
154         printLine($line, STYLE_PLAIN);
155     } elsif ($line =~ /\*\* BUILD SUCCEEDED \*\*/) {
156         printLine("Build Succeeded", STYLE_SUCCESS);
157     } elsif ($line =~ /^(PhaseScriptExecution|CompileC|Distributed-CompileC|Ld|PBXCp|CpResource|CopyPNGFile|CopyTiffFile|CpHeader|Processing|ProcessInfoPlistFile|ProcessPCH|ProcessPCH\+\+|Touch|Libtool|CopyStringsFile|Mig|CreateUniversalBinary|Analyze|ProcessProductPackaging|CodeSign|SymLink|Updating|CompileXIB|StripNIB|CopyPlistFile|GenerateDSYMFile) ("[^"]+"|\S+)?/) {
158         my ($command, $path) = ($1, basename($2));
159         $path =~ s/"//g;
160         printLine("$command $path", STYLE_PLAIN);
161     } elsif ($line =~ /^\/\S+?(strip|WebCoreExportFileGenerator) .*?(\/|\> )(\S+)/) {
162         my ($command, $path) = (basename($1), basename($3));
163         printLine("$command $path", STYLE_PLAIN);
164     } elsif ($line =~ /^offlineasm\: /) {
165         printLine($line, STYLE_PLAIN);
166     } elsif ($line =~ /^Generating message.*(header|receiver) for (\S+)\.\.\./) {
167         my ($command, $path) = ($1, basename($2));
168         printLine("Generating message $command $path", STYLE_PLAIN);
169     } elsif ($line =~ /^(\S+\/cc).*?(\S+)\.(out|exp)/) {
170         my ($command, $path) = (basename($1), basename($2));
171         printLine("$command $path", STYLE_PLAIN);
172     } else {
173         # This only gets hit if stderr is redirected to stdout.
174         if ($line =~ /\*\* BUILD FAILED \*\*/) {
175             $buildFailed = 1;
176         }
177         printLine($line, $buildFinished ? STYLE_SUCCESS : STYLE_ALERT);
178     }
179 }
180
181 print OUTPUT_HANDLE HTML_FOOTER if ($outputFormat eq "html");
182
183 close(OUTPUT_HANDLE);
184 close(UNFILTERED_OUTPUT_HANDLE) if ($logUnfilteredOutput);
185
186 exit $buildFailed;
187
188 sub printLine($$)
189 {
190     my ($line, $style) = @_;
191
192     if ($outputFormat eq "html") {
193         $line = escapeHTML($line);
194         if    ($style == STYLE_HEADER)  { print OUTPUT_HANDLE "<h2>$line</h2>"; }
195         elsif ($style == STYLE_SUCCESS) { print OUTPUT_HANDLE "<p class=\"success\">$line</p>"; }
196         elsif ($style == STYLE_ALERT)   { print OUTPUT_HANDLE "<p class=\"alert\">$line</p>"; }
197         else                            { print OUTPUT_HANDLE "<p>$line</p>"; }
198     } else {
199         if ($useColor) {
200             my $colors = "reset";
201             if ($style == STYLE_HEADER)  { $colors = "blue"; }
202             if ($style == STYLE_SUCCESS) { $colors = "green"; }
203             if ($style == STYLE_ALERT)   { $colors = "red"; }
204             print OUTPUT_HANDLE possiblyColored($colors, $line);
205         } else {
206             print OUTPUT_HANDLE $line;
207         }
208     }
209     print OUTPUT_HANDLE "\n";
210 }
211
212 sub setLogfileOption($$)
213 {
214     my ($opt, $value) = @_;
215     $unfilteredOutputPath = $value;
216     $logUnfilteredOutput = 1;
217 }
218
219 sub setOutputFormatOption($$)
220 {
221     my ($opt, $value) = @_;
222     $value = lc($value);
223     if ($value ne "html" && $value ne "text") {
224         die "The $opt option must be either \"html\" or \"text\"";
225     }
226     $outputFormat = $value;
227 }