find-build-errors revision 919
493N/A#! /usr/perl5/bin/perl -w
493N/A
493N/A#
702N/A# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
493N/A# Use is subject to license terms.
493N/A#
493N/A# Permission is hereby granted, free of charge, to any person obtaining a
919N/A# copy of this software and associated documentation files (the "Software"),
919N/A# to deal in the Software without restriction, including without limitation
919N/A# the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A# and/or sell copies of the Software, and to permit persons to whom the
919N/A# Software is furnished to do so, subject to the following conditions:
919N/A#
919N/A# The above copyright notice and this permission notice (including the next
919N/A# paragraph) shall be included in all copies or substantial portions of the
919N/A# Software.
919N/A#
919N/A# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A# DEALINGS IN THE SOFTWARE.
493N/A#
493N/A#
493N/A
493N/Arequire 5.005; # minimal Perl version required
493N/Ause strict; #
493N/Ause diagnostics; #
493N/Ause File::Spec; # pathname manipulation routines
493N/Ause File::stat; # Named results from stat() function
493N/Ause English qw( -nomatchvars );
493N/A
493N/Amy $default_logfile = 'buildit-XW';
493N/Amy $default_logpath = 'log/' . $default_logfile;
493N/Amy $default_pkglogpath = 'proto-packages/logs/package_build';
493N/Amy $logfile;
493N/Amy $pkglog;
493N/Amy $pkgfailed;
493N/A
493N/Aif (defined $ARGV[0]) {
493N/A if (-d $ARGV[0]) {
493N/A $logfile = $ARGV[0] . '/' . $default_logpath;
493N/A } elsif ($ARGV[0] =~ m{/package_build$}ms) {
493N/A $pkglog = $ARGV[0];
493N/A } else {
493N/A $logfile = $ARGV[0];
493N/A }
493N/A} elsif ( -f $default_logfile ) {
493N/A $logfile = $default_logfile;
493N/A} elsif ( -f $default_logpath ) {
493N/A $logfile = $default_logpath;
493N/A} else {
493N/A my @dirtree = File::Spec->splitdir(
493N/A File::Spec->rel2abs(File::Spec->curdir()));
493N/A
493N/A # climb the tree, removing one parent at a time to find the logfile
493N/A while (scalar(@dirtree) > 0) {
493N/A $logfile = File::Spec->catfile( @dirtree, $default_logpath);
493N/A last if ( -f $logfile);
493N/A# print "$logfile not found\n";
493N/A pop @dirtree;
493N/A }
493N/A
493N/A if (scalar(@dirtree) == 0) {
493N/A die "$default_logfile not found, please specify path to log\n";
493N/A }
493N/A}
493N/A
493N/Aif (defined $logfile) {
493N/A open my $LOGFILE, '<', $logfile
493N/A or die "Can't open '$logfile': $OS_ERROR";
493N/A
493N/A print "Scanning $logfile for error messages...\n\n";
493N/A
493N/A my @steplines;
493N/A my $found_error = 0;
493N/A
493N/A while (my $l = <$LOGFILE>) {
493N/A # Finished if we see the end line
493N/A last if $l =~ m{Finished building the X Window System Consolidation}ms;
493N/A
493N/A # Clear saved lines for each new module/subdir
493N/A if (($l =~ m{^\#\# making \S+ in \S+\.\.\.$}ms) || # open-src pattern
810N/A ($l =~ m{^dmake: Warning: Target `subdirs' not remade because of errors}ms) ||
493N/A ($l =~ m{^\S+ing( \S+)* in \S+\.\.\.$}ms)) { # xc pattern
493N/A @steplines = ();
493N/A $found_error = 0;
493N/A }
493N/A
493N/A # If we already hit an error, skip the rest of this module
493N/A next if ($found_error != 0);
493N/A
493N/A # Add this line to the saved output, combine with previous if previous
493N/A # ended with an \
493N/A if (($#steplines >= 0) && ($steplines[$#steplines] =~ m{\\\Z}ms)) {
493N/A $steplines[$#steplines] .= $l;
493N/A } else {
493N/A push @steplines, $l;
493N/A }
493N/A
493N/A # Skip ahead to next line if this line ends with \
493N/A next if ($l =~ m{\\\Z}ms);
493N/A
493N/A # Found a new error?
810N/A if (($l =~ m{\*\*\* }ms) || ($l =~ m{^make: Fatal error}ms)) {
493N/A $found_error = 1;
493N/A
493N/A # Print section header
493N/A print $steplines[0], "\n";
493N/A
493N/A my $lastmake;
493N/A my $lastcommand = 1;
493N/A my $lastplus = 0;
493N/A
493N/A # scan back to figure out how far back to print
493N/A for my $ln (1..($#steplines - 1)) {
493N/A my $sl = $steplines[$ln];
493N/A
493N/A # print "lastmake: $lastmake, lastcom: $lastcommand, lastplus: $lastplus, line #$ln: $sl\n";
810N/A if ($sl =~ m{\b(make|dmake|gmake)\b}ms) {
493N/A $lastmake = $ln;
493N/A }
493N/A
493N/A if ($sl =~ m{\breturned\b}ms) {
493N/A # don't treat this as a command
810N/A } elsif ($sl =~ m{\b(cc|gcc|CC|g\+\+|ld|gpatch|libtool|GEN|CCLD)\s+}ms) {
493N/A if ($sl !~ m{usage:}) {
493N/A $lastcommand = $ln;
493N/A }
493N/A } elsif ($sl =~ m{^\+ }ms) {
493N/A # print from start of shell's set -x output, not end
493N/A if ($lastplus != ($ln - 1)) {
493N/A $lastcommand = $ln;
493N/A }
493N/A $lastplus = $ln;
493N/A } elsif ($lastplus == ($ln - 1)) {
493N/A $lastcommand = $ln;
493N/A }
493N/A }
493N/A
493N/A # print "lastmake: $lastmake, lastcommand: $lastcommand\n";
493N/A if ($lastmake && ($lastmake < $lastcommand)) {
493N/A print $steplines[$lastmake];
493N/A }
493N/A
493N/A for my $ln ($lastcommand..$#steplines) {
493N/A print $steplines[$ln];
493N/A }
493N/A print "\n", '-'x78, "\n";
493N/A }
493N/A }
493N/A
493N/A my $printme = 0;
493N/A
493N/A # end of file stuff
493N/A while (my $l = <$LOGFILE>) {
493N/A if ($l =~ m{^Runtime: }) {
493N/A print $l;
493N/A next;
493N/A }
493N/A
493N/A # Look for package build results
493N/A if ($l =~ m{^result log is in (.*/package_build)$}ms) {
493N/A $pkglog = $1;
493N/A } elsif ($l =~ m{^Packages built:}ms) {
493N/A print $l;
493N/A } elsif ($l =~ m{^Packages failed:\s+(\d+)}ms) {
493N/A $pkgfailed = $1;
493N/A print $l;
493N/A }
493N/A # print lines where messages about COPYING file errors appear
493N/A # between "Copying package descriptions" & "Building packages"
493N/A elsif ($l =~ m{Copying package descriptions}) {
493N/A $printme = 1;
493N/A } elsif ($l =~ m{Building packages}) {
493N/A $printme = 0;
493N/A }
493N/A elsif ($printme == 1) {
493N/A print $l;
493N/A }
493N/A }
493N/A
493N/A close($LOGFILE);
493N/A}
493N/A
493N/Asub check_pkglog {
493N/A my ($pl) = @_;
493N/A
493N/A if ( -f $pl ) {
493N/A my $logfile_sb = stat($logfile);
493N/A my $pkglog_sb = stat($pl);
493N/A
493N/A if ($logfile_sb > $pkglog_sb) {
493N/A # Haven't rebuilt packages since last build, so no point reporting errors
493N/A undef $pl;
493N/A }
493N/A } else {
493N/A undef $pl;
493N/A }
493N/A
493N/A return $pl;
493N/A}
493N/A
493N/A# No packaging log found in build log, try to guess where it is
493N/Aif (!defined($pkglog)) {
493N/A my $path_to_check = $logfile;
493N/A $path_to_check =~ s{$default_logpath}{$default_pkglogpath}ms;
493N/A
493N/A $pkglog = check_pkglog($path_to_check);
493N/A
493N/A if (!defined($pkglog)) {
493N/A $path_to_check = $logfile;
493N/A $path_to_check =~ s{($default_logpath).*$}{$default_pkglogpath}ms;
493N/A
493N/A $pkglog = check_pkglog($path_to_check);
493N/A }
493N/A}
493N/A
493N/Aif ((!defined($pkgfailed) || ($pkgfailed > 0)) && defined($pkglog)) {
493N/A open my $PKGLOG, '<', $pkglog
493N/A or die "Can't open '$pkglog': $OS_ERROR";
493N/A
493N/A my @pkglines;
493N/A
493N/A while (my $l = <$PKGLOG>) {
493N/A # Clear saved lines for each new package
493N/A if ($l =~ m{^[*]+ Making the \S+ package [*]+$}ms) {
493N/A @pkglines = ();
493N/A }
493N/A
702N/A # Warnings we can ignore
702N/A next if $l =~ m{^WARNING: parameter \<PSTAMP\> set}ms;
702N/A next if $l =~ m{^WARNING: parameter \<CLASSES\> set to "none"}ms;
702N/A
702N/A push @pkglines, $l;
702N/A
702N/A if (($l =~ m{(Packaging was not successful.|was not found ; skipping)}ms)
702N/A || ($l =~ m{^WARNING: }ms)) {
493N/A print join('', @pkglines);
702N/A @pkglines = ();
493N/A }
493N/A }
493N/A
493N/A close($PKGLOG);
493N/A}