#!/usr/pkg/bin/perl # $NetBSD: post-build,v 1.55 2005/05/19 20:56:36 kristerw Exp $ # # Collect stuff after a pkg bulk build # # (c) 2000 Hubert Feyrer, All Rights Reserved. # use File::Basename; use POSIX qw(strftime); use strict; use warnings; my %vars; my $verbose = 1; # set to 2 to see more command execution detail sub my_system (@) { print STDERR '> '.join(' ', @_)."\n" if ($verbose >= 2); system(@_); } # Where config vars are stored (/bin/sh syntax) my $BULK_BUILD_CONF = $ENV{BULK_BUILD_CONF} || (dirname($0).'/build.conf'); $BULK_BUILD_CONF = "./$BULK_BUILD_CONF" if ($BULK_BUILD_CONF !~ m:^/:); # Dig given variable out of config file, and set it sub getconf (@) { open(I, ". $BULK_BUILD_CONF; for var in ".join(' ', @_)."; do eval echo \\\${\$var}; done |") || die 'cannot open pipe'; foreach my $var (@_) { $vars{$var} = ; chomp $vars{$var}; die "\$$var not defined by $BULK_BUILD_CONF" if ($vars{$var} eq ''); print STDERR "> $var=$vars{$var}\n" if ($verbose >= 2); } } getconf( 'ADMINSIG', # "-Your Name" 'FTPURL', # "pub/NetBSD/pkgstat/`date +%Y%m%d.%H%M`" 'FTP', # "/disk1/ftp/${FTPURL}" 'FTPHOST', # ftp://ftp.machi.ne/ 'REPORT', # "broken.html" 'USR_PKGSRC', # "/usr/pkgsrc" 'osrev', # `uname -r` ); my $reportf = basename($vars{REPORT}); my $os = `uname -s`; chomp $os; my $BMAKE = $ENV{BMAKE} || die '$BMAKE not defined in environment'; sub getmakevars (@) { open(I, "cd $vars{USR_PKGSRC}/pkgtools/pkglint && $BMAKE show-vars BATCH=1 VARNAMES='".join(' ', @_)."' |") || die 'cannot open pipe'; foreach my $var (@_) { $vars{$var} = ; chomp $vars{$var}; die "\${$var} not defined by $BMAKE" if ($vars{$var} eq ''); print STDERR "> $var=$vars{$var}\n" if ($verbose >= 2); } } # Extract the names of the files used for the build log and broken build logs. # These have defaults set by bsd.bulk-pkg.mk and may be overridden in # /etc/mk.conf getmakevars(qw( BROKENFILE BROKENWRKLOG BULK_DBFILE DEPENDSFILE DEPENDSTREEFILE FIND INDEXFILE LOCALBASE MACHINE_ARCH ORDERFILE PAX PKG_DBDIR STARTFILE SUPPORTSFILE X11BASE )); my $bulkdbfile = basename($vars{BULK_DBFILE}); my $dtfile = basename($vars{DEPENDSTREEFILE}); my $depfile = basename($vars{DEPENDSFILE}); my $supfile = basename($vars{SUPPORTSFILE}); my $indfile = basename($vars{INDEXFILE}); my $ordfile = basename($vars{ORDERFILE}); my $startdate = (stat($vars{STARTFILE}))[9]; my $enddate = ''; if ($startdate == 0) { $startdate = "unknown"; } else { local $ENV{TZ} = "UTC"; $startdate = strftime("%c %Z", gmtime($startdate)); $enddate = strftime("%c %Z", gmtime(time())); } my $report_head = </dev/null | $vars{PAX} -r -w -X -p e $vars{FTP}"); # Copy over the cache files used during the build foreach my $f qw(BULK_DBFILE DEPENDSTREEFILE DEPENDSFILE SUPPORTSFILE INDEXFILE ORDERFILE) { my_system("cp $vars{$f} $vars{FTP}") if -f $vars{$f}; } chdir($vars{FTP}); writeReport(); # # Adjust "last" symlink # { my ($base, $dir) = ($vars{FTP} =~ m|^(.*)/([^/]*)$|); unlink("$base/last"); symlink($dir, "$base/last"); } # # Generate leftovers-$vars{MACHINE_ARCH}.html: files not deleted # Leftover files are copied to leftovers-$vars{MACHINE_ARCH} dir, # and linked from leftovers-$vars{MACHINE_ARCH}.html # { chdir($vars{FTP}); my_system("mkdir -p leftovers-$vars{MACHINE_ARCH}"); # Find files since last build: my $leftovers_txt = "leftovers-$vars{MACHINE_ARCH}.txt"; my $leftovers_html = "leftovers-$vars{MACHINE_ARCH}.html"; my_system("$vars{FIND} $vars{LOCALBASE}/ -newer $vars{STARTFILE} -type f -print >>$leftovers_txt"); my_system("$vars{FIND} $vars{X11BASE}/ -newer $vars{STARTFILE} -type f -print >>$leftovers_txt"); # Strip perl-files: my $perlfiles; { local $/; undef $/; $perlfiles = `pkg_info -qL perl*`; } my $perlfiles_pattern = $perlfiles; $perlfiles_pattern =~ s/\n/|/g; $perlfiles_pattern =~ s/|$//; open (LEFT, $leftovers_txt) or die "can't read $leftovers_txt: $!"; my @left = ; close (LEFT); my @leftovers = grep(!/^(?:${perlfiles_pattern})$/, @left); if (index($vars{PKG_DBDIR}, $vars{LOCALBASE}) == 0) { # If PKG_DBDIR is inside LOCALBASE, exclude it from the leftovers. @leftovers = grep { index($_, $vars{PKG_DBDIR}) != 0 } @leftovers; } open (LEFT, ">$leftovers_txt") or die "can't write $leftovers_txt: $!"; print LEFT @leftovers; close (LEFT); if (scalar(@leftovers)) { # Store leftovers, for easier identification: my_system("$vars{PAX} -r -w -X -p e leftovers-$vars{MACHINE_ARCH} < $leftovers_txt"); } # Add links to leftover list: open (OUT, "> $leftovers_html") or die "can't write $leftovers_html"; print OUT <
EOOUT
	foreach (@leftovers) {
		chomp;
	    	print OUT "$_\n";
	}
	print OUT <


EOOUT2
    	close(OUT);
}

# print the result of a single broken package
sub pkgResult ($$) {
	my ($pinfo, $state) = @_;
	my $pkg = $pinfo->{pkg};
	my $nbrokenby = $pinfo->{nbrokenby};
	my $nerrors = $pinfo->{nerrors};

	my @idents = `$vars{FIND} $vars{USR_PKGSRC}/$pkg -type f -print | xargs grep \\\$NetBSD`;
	my $datetime = "";
	my $file = "";
	my $ver = "";
	foreach my $ident (@idents) {
		$ident =~ /\$[N]etBSD: ([^ ]*),v [^ ]* ([^ ]*) ([^ ]*) [^ ]* Exp \$/;
		if (defined($2) && defined($3) && ("$2 $3" gt $datetime)) {
			$datetime = "$2 $3";
			$file = $1;
			$ver = $1;
		}
	}

	my $maintainer = `grep ^MAINTAINER $vars{USR_PKGSRC}/$pkg/Makefile`;
	$maintainer =~ s/MAINTAINER=[ \t]*//;
	if (! $maintainer) {
		 $maintainer = `cd $vars{USR_PKGSRC}/$pkg ; $BMAKE show-var VARNAME=MAINTAINER`;
	}
	$maintainer =~ s//>/g;
	chomp($maintainer);

	(my $state_style = $state) =~ s/ //g;

	my $nbrokenby_html = ' '; 
	$nbrokenby_html =
		''.$nbrokenby.''
		if $nbrokenby > 0;

	if ($pinfo->{nerrors} != 0 && $verbose && ($state eq "broken" || $state eq "topten")) {
		print swrite($report_form, $pkg, $nbrokenby > 0 ? $nbrokenby : "", $maintainer);
	}

	return <
  $pkg
  $nbrokenby_html
  $file
  $maintainer


EOHTML
}

# write the build report
sub writeReport {
	my $broken = getBroken();
	my $nbroken = scalar(@{$broken->{"broken"}});
	my $nbrokendep = scalar(@{$broken->{"broken depends"}});
	my $nunpackaged = scalar(@{$broken->{"not packaged"}});
	my $nbrokentot = $nbroken + $nbrokendep;
	my $ntotal = $nunpackaged + $nbroken + $nbrokendep;

	# determine the number of packages attempted, and then successful
	open(ORDER, $vars{ORDERFILE}) || die "can't open $vars{ORDERFILE}: $!";
	my @order = ;
	close(ORDER);
	my $nattempted = scalar(@order);
	my $nsuccessful = $nattempted - $ntotal;

	if ($verbose) {
		print <$vars{REPORT}") or die "Can't write $vars{REPORT}: $!\n";
	print HTML <

$os $vars{osrev}/$vars{MACHINE_ARCH} bulk package build






pkgsrc bulk build results

$os $vars{osrev}/$vars{MACHINE_ARCH}

Summary

Build started: $startdate
Build ended: $enddate
   
Successfully packaged: $nsuccessful
Packages really broken: $nbroken
Packages broken due to them: $nbrokendep
Total broken: $nbrokentot
Not packaged: $nunpackaged
Total: $ntotal

Packages not listed here resulted in a binary package. Results of failed packages are available below.

Files leftover from the build (because of broken PLISTs, etc.) can be found in this list.

Jump to:

EOHTML my %state_head = ( "topten" => "Top Ten Offenders", "broken" => "Broken packages", "broken depends" => "Broken dependencies", "not packaged" => "Not packaged" ); foreach my $state ("topten", "broken", "broken depends", "not packaged") { next unless scalar(@{$broken->{$state}}); if ($verbose && ($state eq "topten" || $state eq "broken")) { print "\n\n$state_head{$state}\n\n"; print $report_head; } print HTML <

$state_head{$state}

EOHTML foreach my $pinfo (@{$broken->{$state}}) { print HTML pkgResult($pinfo, $state); } print HTML <
Up to top

EOHTML } print HTML <

The following cache files were used during the build:


EOHTML close(HTML); if ($verbose) { print "\n\n$vars{ADMINSIG}\n\n"; print "[* This message was created by the Packages Collection bulk build software *]\n"; } } # get and sort the broken packages sub getBroken { my $res = { 'broken' => [], 'broken depends' => [], 'not packaged' => [], }; open (BF, $vars{BROKENFILE}) || return $res; my @in = ; close (BF); foreach (@in) { chomp; my ($nerrors, $bf, $nbrokenby) = split; my $pkg = $bf; $pkg =~ s,/$vars{BROKENFILE},,; my %tmp = ( bf => $bf, pkg => $pkg, nbrokenby => $nbrokenby, nerrors => $nerrors, ); if ($nerrors > 0) { push(@{$res->{"broken"}}, \%tmp); } elsif ($nerrors == -1) { push(@{$res->{"broken depends"}}, \%tmp); } else { push(@{$res->{"not packaged"}}, \%tmp); } } # sort pkgs in each state foreach my $state ("broken", "broken depends", "not packaged") { $res->{$state} = [ sort { $a->{pkg} cmp $b->{pkg} } @{$res->{$state}} ]; } $res->{"topten"} = [ sort { $b->{nbrokenby} <=> $a->{nbrokenby} } @{$res->{"broken"}} ]; for (my $count = $#{$res->{"topten"}}; $count >= 10; $count--) { pop(@{$res->{"topten"}}); } return $res; } sub swrite { my $format = shift; $^A = ""; formline($format, @_); $^A =~ s/\n\n/\n/; return $^A; }
Package Breaks File touched last Maintainer