--- a/open-src/util/build-tools/find-build-errors Wed Jun 30 14:10:39 2010 -0700
+++ b/open-src/util/build-tools/find-build-errors Fri Jul 02 21:03:57 2010 -0700
@@ -1,7 +1,7 @@
#! /usr/perl5/bin/perl -w
#
-# Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -32,17 +32,34 @@
use English qw( -nomatchvars );
my $default_logfile = 'buildit-XW';
+# Log file from new pkg(5) build (in same directory as $default_logfile)
+my $default_ips_pkglogfile = 'make-pkgs';
+# Log file from old SVR4 package build:
my $default_logpath = 'log/' . $default_logfile;
-my $default_pkglogpath = 'proto-packages/logs/package_build';
+my $default_svr4_pkglogpath = 'proto-packages/logs/package_build';
my $logfile;
my $pkglog;
+my $pkglog_type; # 'ips' or 'svr4'
my $pkgfailed;
+my $summary_only = 0;
+
+if (defined $ARGV[0] && $ARGV[0] eq '-s') {
+ $summary_only = 1;
+ shift @ARGV;
+}
if (defined $ARGV[0]) {
if (-d $ARGV[0]) {
$logfile = $ARGV[0] . '/' . $default_logpath;
+ } elsif ($ARGV[0] =~ m{/make-pkgs$}ms) {
+ $pkglog = $ARGV[0];
+ $pkglog_type = 'ips';
+ } elsif ($ARGV[0] =~ m{/check-pkgs$}ms) {
+ $pkglog = $ARGV[0];
+ $pkglog_type = 'validate';
} elsif ($ARGV[0] =~ m{/package_build$}ms) {
$pkglog = $ARGV[0];
+ $pkglog_type = 'svr4';
} else {
$logfile = $ARGV[0];
}
@@ -68,6 +85,56 @@
}
if (defined $logfile) {
+ my $make_errors = 0;
+ my $LOGFILE = check_make_log($logfile, \$make_errors);
+
+ print "Build errors: ", $make_errors, "\n";
+
+ my $printme = 0;
+
+ # end of file stuff
+ while (my $l = <$LOGFILE>) {
+ if ($l =~ m{^Runtime: }) {
+ print $l;
+ next;
+ }
+
+ # Look for package build results
+ if ($l =~ m{^result log is in (\S*)$}ims) {
+ $pkglog = $1;
+ if ($1 =~ m{/package_build$}ms) {
+ $pkglog_type = 'svr4';
+ } else {
+ $pkglog_type = 'ips';
+ }
+ } elsif ($l =~ m{^Packages built:}ms) {
+ print $l;
+ } elsif ($l =~ m{^Package.* failed:\s+(\d+)}ms) {
+ $pkgfailed = $1;
+ print $l;
+ }
+ # print lines where messages about COPYING file errors appear
+ # between "Copying package descriptions" & "Building packages"
+ elsif ($l =~ m{Copying package descriptions}) {
+ $printme = 1;
+ } elsif ($l =~ m{Building packages}) {
+ $printme = 0;
+ }
+ elsif ($printme == 1) {
+ print $l;
+ }
+ }
+ print "\n";
+
+ close($LOGFILE);
+}
+
+# Input: string containing name of logfile
+# Prints errors from make output log
+# Returns open log file pointer for post-processing
+sub check_make_log {
+ my ($logfile, $error_count_ref) = @_;
+
open my $LOGFILE, '<', $logfile
or die "Can't open '$logfile': $OS_ERROR";
@@ -75,6 +142,7 @@
my @steplines;
my $found_error = 0;
+ my $error_count = 0;
while (my $l = <$LOGFILE>) {
# Finished if we see the end line
@@ -83,6 +151,7 @@
# Clear saved lines for each new module/subdir
if (($l =~ m{^\#\# making \S+ in \S+\.\.\.$}ms) || # open-src pattern
($l =~ m{^dmake: Warning: Target `subdirs' not remade because of errors}ms) ||
+ ($l =~ m{^\#\# [[:upper:]][[:lower:]]+ing }ms) || # pkg pattern
($l =~ m{^\S+ing( \S+)* in \S+\.\.\.$}ms)) { # xc pattern
@steplines = ();
$found_error = 0;
@@ -103,8 +172,11 @@
next if ($l =~ m{\\\Z}ms);
# Found a new error?
- if (($l =~ m{\*\*\* }ms) || ($l =~ m{^make: Fatal error}ms)) {
+ if (($l =~ m{\*\*\* }ms) || ($l =~ m{^(d)?make: Fatal error}ms)) {
$found_error = 1;
+ $error_count++;
+
+ next if ($summary_only);
# Print section header
print $steplines[0], "\n";
@@ -151,37 +223,11 @@
}
}
- my $printme = 0;
-
- # end of file stuff
- while (my $l = <$LOGFILE>) {
- if ($l =~ m{^Runtime: }) {
- print $l;
- next;
- }
-
- # Look for package build results
- if ($l =~ m{^result log is in (.*/package_build)$}ms) {
- $pkglog = $1;
- } elsif ($l =~ m{^Packages built:}ms) {
- print $l;
- } elsif ($l =~ m{^Packages failed:\s+(\d+)}ms) {
- $pkgfailed = $1;
- print $l;
- }
- # print lines where messages about COPYING file errors appear
- # between "Copying package descriptions" & "Building packages"
- elsif ($l =~ m{Copying package descriptions}) {
- $printme = 1;
- } elsif ($l =~ m{Building packages}) {
- $printme = 0;
- }
- elsif ($printme == 1) {
- print $l;
- }
+ if (defined $error_count_ref) {
+ ${$error_count_ref} = $error_count;
}
- close($LOGFILE);
+ return $LOGFILE;
}
sub check_pkglog {
@@ -191,7 +237,7 @@
my $logfile_sb = stat($logfile);
my $pkglog_sb = stat($pl);
- if ($logfile_sb > $pkglog_sb) {
+ if ($logfile_sb->mtime > $pkglog_sb->mtime) {
# Haven't rebuilt packages since last build, so no point reporting errors
undef $pl;
}
@@ -205,42 +251,156 @@
# No packaging log found in build log, try to guess where it is
if (!defined($pkglog)) {
my $path_to_check = $logfile;
- $path_to_check =~ s{$default_logpath}{$default_pkglogpath}ms;
+ $path_to_check =~ s{$default_logfile}{$default_ips_pkglogfile}ms;
$pkglog = check_pkglog($path_to_check);
- if (!defined($pkglog)) {
+ if (defined($pkglog)) {
+ $pkglog_type = 'ips';
+ } else {
+ $pkglog_type = 'svr4';
+
$path_to_check = $logfile;
- $path_to_check =~ s{($default_logpath).*$}{$default_pkglogpath}ms;
+ $path_to_check =~ s{$default_logpath}{$default_svr4_pkglogpath}ms;
$pkglog = check_pkglog($path_to_check);
+ if (!defined($pkglog)) {
+ $path_to_check = $logfile;
+ $path_to_check =~ s{($default_logpath).*$}{$default_svr4_pkglogpath}ms;
+
+ $pkglog = check_pkglog($path_to_check);
+ }
}
}
+
if ((!defined($pkgfailed) || ($pkgfailed > 0)) && defined($pkglog)) {
- open my $PKGLOG, '<', $pkglog
- or die "Can't open '$pkglog': $OS_ERROR";
+ if ($pkglog_type eq 'svr4') {
+ open my $PKGLOG, '<', $pkglog
+ or die "Can't open '$pkglog': $OS_ERROR";
+
+ my @pkglines;
+
+ while (my $l = <$PKGLOG>) {
+ # Clear saved lines for each new package
+ if ($l =~ m{^[*]+ Making the \S+ package [*]+$}ms) {
+ @pkglines = ();
+ }
+
+ # Warnings we can ignore
+ next if $l =~ m{^WARNING: parameter \<PSTAMP\> set}ms;
+ next if $l =~ m{^WARNING: parameter \<CLASSES\> set to "none"}ms;
+
+ push @pkglines, $l;
- my @pkglines;
+ if (($l =~ m{(Packaging was not successful.|was not found ; skipping)}ms)
+ || ($l =~ m{^WARNING: }ms)) {
+ print join('', @pkglines);
+ @pkglines = ();
+ }
+ }
+ close($PKGLOG);
+ } elsif ($pkglog_type eq 'ips') {
+ my $ips_count_errors = 0;
+ my $PKGLOG = check_make_log($pkglog, \$ips_count_errors);
- while (my $l = <$PKGLOG>) {
- # Clear saved lines for each new package
- if ($l =~ m{^[*]+ Making the \S+ package [*]+$}ms) {
- @pkglines = ();
+ seek($PKGLOG, 0, 0); # reset to start reading from beginning of file
+
+ my $ips_count_published = 0;
+
+ while (my $l = <$PKGLOG>) {
+ if ($l =~ m{Publishing .* to proto repository}) {
+ $ips_count_published++;
+ }
}
- # Warnings we can ignore
- next if $l =~ m{^WARNING: parameter \<PSTAMP\> set}ms;
- next if $l =~ m{^WARNING: parameter \<CLASSES\> set to "none"}ms;
+ print "Packages published: $ips_count_published\n";
+ print "Package build errors: $ips_count_errors\n";
+ } elsif ($pkglog_type eq 'validate') { # validate_pkg
+ open my $PKGLOG, '<', $pkglog
+ or die "Can't open '$pkglog': $OS_ERROR";
+
+ my @pkglines;
+ my $issue_count = 0;
+ my $issue_type = "";
+
+ while (my $l = <$PKGLOG>) {
+ chomp($l);
+
+ # Clear saved lines for each new class of issue
+ if ($l =~ m{^\S+ .*:+$}ms) {
+ $issue_type = $l;
+ $issue_count = 0;
+ @pkglines = ();
+ next;
+ }
- push @pkglines, $l;
+ # These issues print across two lines
+ if ($issue_type eq
+ 'Entries that differ between manifests and proto area:')
+ {
+ if ($l =~ m{^\s+manifests }) {
+ my $l2 = <$PKGLOG>;
+ chomp($l2);
+
+ # strip off prefixes for comparisons
+ my $compare1 = $l;
+ $compare1 =~ s{^\s+manifests }{};
+ my $compare2 = $l2;
+ $compare2 =~ s{^\s+proto area }{};
+
+ # Warnings we can ignore
+ if ($compare1 =~ m{^hardlink }) {
+ my $hl1 = $compare1;
+ my $hl2 = $compare2;
+
+ # validate_pkg doesn't like hardlinks to isaexec from our pkgs
+ $hl1 =~ s{ target=usr/lib/isaexec}{};
+ $hl2 =~ s{ target=\d+}{};
- if (($l =~ m{(Packaging was not successful.|was not found ; skipping)}ms)
- || ($l =~ m{^WARNING: }ms)) {
- print join('', @pkglines);
- @pkglines = ();
+ next if ($hl1 eq $hl2);
+
+ } elsif ($compare1 =~ m{^file }) {
+ my $f1 = $compare1;
+ my $f2 = $compare2;
+
+ $f1 =~ s{^file NOHASH }{ };
+ $f2 =~ s{^file \S+ }{ };
+
+ # We don't expect files in proto area to be chowned/chgrped
+ $f1 =~ s{ owner=root}{};
+ $f2 =~ s{ owner=owner}{};
+ $f1 =~ s{ group=\S+}{};
+ $f2 =~ s{ group=group}{};
+
+ # We don't expect files in proto area to be setuid/setgid
+ if ($f1 =~ m{mode=[24]555}) {
+ $f1 =~ s{ mode=[24]555}{};
+ $f2 =~ s{ mode=0555}{};
+ }
+
+ next if ($f1 eq $f2);
+ }
+
+ $l .= "\n" . $l2 . "\n";
+ }
+ }
+
+ if ($l =~ m{^$}) { # Blank lines separate sections
+ if ($issue_count > 0) {
+ if ($summary_only) {
+ print $issue_type, ' ', $issue_count, "\n";
+ } else {
+ print join("\n", $issue_type, '', @pkglines), "\n\n";
+ }
+ }
+ @pkglines = ();
+ } else {
+ push @pkglines, $l;
+ $issue_count++;
+ }
+
}
+ close($PKGLOG);
}
-
- close($PKGLOG);
}