Somethings not working. Backup

This commit is contained in:
slamm%netscape.com 1999-10-29 18:54:32 +00:00
Родитель 28183cec5b
Коммит 12bc6ea86c
2 изменённых файлов: 552 добавлений и 461 удалений

Просмотреть файл

@ -29,7 +29,7 @@ $default_root = '/cvsroot';
# Show 12 hours by default
#
$nowdate = time;
$nowdate = time;
if (not defined($maxdate = $form{maxdate})) {
$maxdate = $nowdate;
}
@ -57,16 +57,10 @@ else {
$tree = $form{tree};
# $rel_path is the relative path to webtools/tinderbox used for links.
# It changes to "../" if the page is generated statically, because then
# it is placed in tinderbox/$tree.
$rel_path = '';
if (exists $form{rebuildguilty} or exists $form{showall}) {
system ("./buildwho.pl -days 7 $tree > /dev/null");
undef $form{rebuildguilty};
}
&show_tree_selector, exit if $form{tree} eq '';
&do_quickparse, exit if $form{quickparse};
&do_express, exit if $form{express};
@ -151,7 +145,7 @@ sub do_static {
}
sub do_tinderbox {
&tb_load_data;
&load_data;
&print_page_head;
&print_table_header;
&print_table_body;
@ -229,152 +223,163 @@ sub print_page_head {
}
sub print_table_body {
for (my $tt=0; $tt < $time_count; $tt++) {
for (my $tt=1; $tt <= $time_count; $tt++) {
last if $build_time_times->[$tt] < $mindate;
print_table_row($tt);
}
}
sub print_bloat_delta {
sub print_delta {
my ($value, $min) = @_;
# this function rounds off, and prints bad (> min) values in red
my $worse = ($value - $min) > 1000; # heuristic -- allow 1k of noise
my $units = 'b';
my $units = "b";
if ($value >= 1000000) {
$value = int($value / 1000000);
$min = int($min / 1000000);
$units = 'M';
} elsif ($value >= 1000) {
$value = int($value / 1000);
$min = int($min / 1000);
$units = 'K';
$value = int($value / 1000000);
$min = int($min / 1000000);
$units = "M";
}
else {
if ($value >= 1000) {
$value = int($value / 1000);
$min = int($min / 1000);
$units = "K";
}
}
if ($worse) {
return sprintf('<b><font color="#FF0000">%d%s</font></b>', $value, $units);
} else {
return sprintf('%d%s', $value, $units);
return sprintf("<b><font color=\"#FF0000\">%d%s</font></b>",
$value, $units);
}
else {
return sprintf("%d%s", $value, $units);
}
}
BEGIN {
# Make $lasthour persistent private variable for print_table_row().
my $lasthour = '';
sub print_table_row {
my ($tt) = @_;
sub print_table_row {
my ($tt) = @_;
# Time column
#
my $query_link = '';
my $end_query = '';
my $pretty_time = &print_time($build_time_times->[$tt]);
# Time column
#
my $query_link = '';
my $end_query = '';
my $pretty_time = &print_time($build_time_times->[$tt]);
($hour) = $pretty_time =~ /(\d\d):/;
($hour) = $pretty_time =~ /(\d\d):/;
if ($lasthour ne $hour or &has_who_list($tt)) {
$query_link = &query_ref($td, $build_time_times->[$tt]);
$end_query = '</a>';
}
if ($lasthour eq $hour) {
$pretty_time =~ s/^.*&nbsp;//;
} else {
$lasthour = $hour;
}
my $hour_color = '';
$hour_color = ' bgcolor=#e7e7e7' if $build_time_times->[$tt] % 7200 <= 3600;
print "<tr align=center><td align=right$hour_color>",
"$query_link\n$pretty_time$end_query</td>\n";
# Guilty
#
print '<td>';
for $who (sort keys %{$who_list->[$tt]} ){
my $qr = &who_menu($td, $build_time_times->[$tt],
$build_time_times->[$tt-1],$who);
$who =~ s/%.*$//;
print " $qr$who</a>\n";
}
print '</td>';
# Build Status
#
for (my $build_index=0; $build_index < $name_count; $build_index++) {
if (not defined($br = $build_table->[$tt][$build_index])) {
# No build data for this time
print "<td></td>\n";
next;
}
next if $br == -1; # rowspan has covered this row
my $rowspan = $br->{rowspan};
$rowspan = $mindate_time_count - $tt + 1
if $tt + $rowspan - 1 > $mindate_time_count;
print "<td rowspan=$rowspan bgcolor=$colormap{$br->{buildstatus}}>\n";
my $logfile = $br->{logfile};
my $buildtree = $br->{td}->{name};
print "<tt>\n";
# Build Note
#
my $logurl = "${rel_path}showlog.cgi?log=$buildtree/$logfile";
if ($br->{hasnote}) {
print "<a href='$logurl' onclick=\"return ",
"note(event,$br->{noteid},'$logfile');\">",
"<img src='$images{star}' border=0></a>\n";
}
# Build Log
#
print "<A HREF='$logurl'"
." onclick=\"return log(event,$build_index,'$logfile');\">"
."L</a>";
# What Changed
#
# Only add the "C" link if there have been changes since the last build.
if( $br->{previousbuildtime} ){
my $previous_br = $build_table->[$tt+$rowspan][$build_index];
my $previous_rowspan = $previous_br->{rowspan};
if (&has_who_list($tt+$rowspan,
$tt+$rowspan+$previous_rowspan-1)) {
print "\n", &query_ref($br->{td},
$br->{previousbuildtime},
$br->{buildtime});
print "C</a>";
}
}
# Leak/Bloat
#
if (defined $bloaty_by_log->{$logfile}) {
my ($leaks, $bloat);
($leaks, $bloat) = @{ $bloaty_by_log->{$logfile} };
printf "<br>Lk:%s<br>Bl:%s",
print_bloat_delta($leaks, $bloaty_min_leaks),
print_bloat_delta($bloat, $bloaty_min_bloat);
}
# Binary
#
if ($br->{binaryname} ne '') {
$binfile = "$buildtree/bin/$br->{buildtime}/$br->{buildname}/"
."$br->{binaryname}";
$binfile =~ s/ //g;
print " <a href=$rel_path$binfile>B</a>";
}
print "</tt>\n</td>";
}
print "</tr>\n";
if ($lasthour != $hour or &has_who_list($tt)) {
$query_link = &query_ref($td1, $build_time_times->[$tt]);
$end_query = '</a>';
}
if ($lasthour == $hour) {
$pretty_time =~ s/^.*&nbsp;//;
} else {
$lasthour = $hour;
}
my $hour_color = '';
$hour_color = ' bgcolor=#e7e7e7' if $build_time_times->[$tt] % 7200 <= 3600;
print "<tr align=center><td align=right$hour_color>",
"$query_link\n$pretty_time$end_query</td>\n";
# Guilty
#
print '<td>';
for $who (sort keys %{$who_list->[$tt]} ){
$qr = &who_menu($td1, $build_time_times->[$tt],
$build_time_times->[$tt-1],$who);
$who =~ s/%.*$//;
print " ${qr}$who</a>\n";
}
print '</td>';
# Build Status
#
for ($bn=1; $bn <= $name_count; $bn++) {
if (not defined($br = $build_table->[$tt][$bn])) {
# No build data for this time
print "<td></td>\n";
next;
}
next if $br == -1; # rowspan has covered this row
$hasnote = $br->{hasnote};
$noteid = $hasnote ? $br->{noteid} : 0;
$rowspan = $br->{rowspan};
$rowspan = $mindate_time_count - $tt + 1
if $tt + $rowspan - 1 > $mindate_time_count;
$color = $colormap{$br->{buildstatus}};
$status = $br->{buildstatus};
print "<td rowspan=$rowspan bgcolor=${color}>\n";
$logfile = $br->{logfile};
$errorparser = $br->{errorparser};
$buildname = $br->{buildname};
$buildtime = $br->{buildtime};
$buildtree = $br->{td}->{name};
print "<tt>\n";
# Build Note
#
$buildname = &url_encode($buildname);
my $logurl = "${rel_path}showlog.cgi?log=$buildtree/$logfile";
if ($hasnote) {
print "<a href='$logurl' onclick=\"return ",
"note(event,$noteid,'$logfile');\">",
"<img src='$images{star}' border=0></a>\n";
}
# Build Log
#
print "<A HREF='$logurl' onclick=\"return log(event,$bn,'$logfile');\">";
print "L</a>";
# What Changed
#
if( $br->{previousbuildtime} ){
my $previous_br = $build_table->[$tt+$rowspan][$bn];
my $previous_rowspan = $previous_br->{rowspan};
if (&has_who_list($tt+$rowspan,
$tt+$rowspan+$previous_rowspan-1)) {
print "\n", &query_ref($br->{td},
$br->{previousbuildtime},
$br->{buildtime});
print "C</a>";
}
}
# Leak/Bloat
#
if (defined $bloat_by_log->{$logfile}) {
my $leaks, $bloat;
($leaks, $bloat) = @{ $bloat_by_log->{$logfile} };
# Percentage, or absolute?
# printf "<br>%+.2f<br>%+.2f", $leaks, $bloat;
#printf "<br>%d<br>%d", $leaks, $bloat;
printf "<br>Lk:%s<br>Bl:%s",
print_delta($leaks, $minLeaks),
print_delta($bloat, $minBloat);
}
# Binary
#
if ($br->{binaryname} ne '') {
$binfile = "$buildtree/bin/$buildtime/$br->{buildname}/"
."$br->{binaryname}";
$binfile =~ s/ //g;
print " <a href=$rel_path$binfile>B</a>";
}
print "</tt>\n</td>";
}
print "</tr>\n";
}
sub print_table_header {
my $ii, $nspan;
print "<table border=1 bgcolor='#FFFFFF' cellspacing=1 cellpadding=1>\n";
print "<tr align=center>\n";
@ -386,14 +391,14 @@ sub print_table_header {
&open_showbuilds_href(rebuildguilty=>'1'),
"Rebuild guilty list</a></td>";
for (my $ii=0; $ii < $name_count; $ii++) {
for ($ii=1; $ii <= $name_count; $ii++) {
my $bn = $build_names->[$ii];
my $bn = $build_name_names->[$ii];
$bn =~ s/Clobber/Clbr/g;
$bn =~ s/Depend/Dep/g;
$bn = "<font face='Helvetica,Arial' size=-1>$bn</font>";
my $last_status = tb_last_status($ii);
my $last_status = &last_status($ii);
if ($last_status eq 'busted') {
if ($form{nocrap}) {
print "<td rowspan=2 bgcolor=$colormap{busted}>$bn</td>";
@ -450,16 +455,24 @@ sub query_ref {
$output .= "&branch=$td->{cvs_branch}" if $td->{cvs_branch} ne 'HEAD';
$output .= "&cvsroot=$td->{cvs_root}" if $td->{cvs_root} ne $default_root;
$output .= "&date=explicit&mindate=$mindate";
$output .= "&maxdate=$maxdate" if $maxdate and $maxdate ne '';
$output .= "&who=$who" if $who and $who ne '';
$output .= "&maxdate=$maxdate" if $maxdate ne '';
$output .= "&who=$who" if $who ne '';
$output .= ">";
}
sub query_ref2 {
my ($td, $mindate, $maxdate, $who) = @_;
return "${rel_path}../bonsai/cvsquery.cgi?module=$td->{cvs_module}"
."&branch=$td->{cvs_branch}&cvsroot=$td->{cvs_root}"
."&date=explicit&mindate=$mindate&maxdate=$maxdate&who="
. url_encode($who);
}
sub who_menu {
my ($td, $mindate, $maxdate, $who) = @_;
my $treeflag;
my $qr = "${rel_path}../registry/who.cgi?email=". url_encode($who)
$qr = "${rel_path}../registry/who.cgi?email=". url_encode($who)
. "&d=$td->{cvs_module}|$td->{cvs_branch}|$td->{cvs_root}|$mindate|$maxdate";
return "<a href='$qr' onclick=\"return who(event);\">";
@ -473,13 +486,14 @@ sub has_who_list {
if (not defined(@who_check_list)) {
# Build a static array of true/false values for each time slot.
$who_check_list[$time_count - 1] = 0;
for (my $tt = 0; $tt < $time_count; $tt++) {
$who_check_list[$tt] = 1 if each %{$who_list->[$tt]};
$who_check_list[$time_count] = 0;
my ($t) = 1;
for (; $t<=$time_count; $t++) {
$who_check_list[$t] = 1 if each %{$who_list->[$t]};
}
}
if ($time2) {
for (my $ii=$time1; $ii<=$time2; $ii++) {
for ($ii=$time1; $ii<=$time2; $ii++) {
return 1 if $who_check_list[$ii]
}
return 0
@ -489,7 +503,7 @@ sub has_who_list {
}
sub tree_open {
my ($line, $treestate);
my $line, $treestate;
open(BID, "<../bonsai/data/$bonsai_tree/batchid.pl")
or print "can't open batchid<br>";
$line = <BID>;
@ -606,9 +620,9 @@ __ENDJS
$ss =~ s/\n/\\n/g;
print "\"$ss\";\n";
}
for ($ii=0; $ii < $name_count; $ii++) {
if (defined($br = $build_table->[0][$ii]) and $br != -1) {
my $bn = $build_names->[$ii];
for ($ii=1; $ii <= $name_count; $ii++) {
if (defined($br = $build_table->[1][$ii]) and $br != -1) {
my $bn = $build_name_names->[$ii];
print "builds[$ii]='$bn';\n";
}
}
@ -634,8 +648,8 @@ __ENDJS
sub do_express {
print "Content-type: text/html\nRefresh: 900\n\n<HTML>\n";
my (%build, %times);
tb_loadquickparseinfo($form{tree}, \%build, \%times);
my %build, %times;
loadquickparseinfo($form{tree}, \%build, \%times);
my @keys = sort keys %build;
my $keycount = @keys;
@ -653,8 +667,8 @@ sub do_express {
sub do_panel {
print "Content-type: text/html\n\n<HTML>\n" unless $form{static};
my (%build, %times);
tb_loadquickparseinfo($form{tree}, \%build, \%times);
my %build, %times;
loadquickparseinfo($form{tree}, \%build, \%times);
print q(
<head>
@ -692,8 +706,8 @@ sub do_panel {
sub do_flash {
print "Content-type: text/rdf\n\n" unless $form{static};
my (%build, %times);
tb_loadquickparseinfo($form{tree}, \%build, \%times);
my %build, %times;
loadquickparseinfo($form{tree}, \%build, \%times);
my ($mac,$unix,$win) = (0,0,0);
@ -764,8 +778,8 @@ sub do_quickparse {
my $state = tree_open() ? "Open" : "Close";
print "State|$t|$bonsai_tree|$state\n";
}
my (%build, %times);
tb_loadquickparseinfo($t, \%build, \%times);
my %build, %times;
loadquickparseinfo($t, \%build, \%times);
foreach my $buildname (sort keys %build) {
print "Build|$t|$buildname|$build{$buildname}\n";
@ -781,8 +795,8 @@ sub do_rdf {
$dirurl =~ s@/[^/]*$@@;
my (%build, %times);
tb_loadquickparseinfo($tree, \%build, \%times);
my %build, %times;
loadquickparseinfo($tree, \%build, \%times);
my $image = "channelok.gif";
my $imagetitle = "OK";

Просмотреть файл

@ -16,9 +16,6 @@
# Corporation. Portions created by Netscape are Copyright (C) 1998
# Netscape Communications Corporation. All Rights Reserved.
# Reading the log backwards saves time when we only want the tail.
use Backwards;
#
# Global variabls and functions for tinderbox
#
@ -27,39 +24,59 @@ use Backwards;
# Global variables
#
# From load_data()
$ignore_builds = {};
$td1 = {};
$td2 = {};
# From get_build_name_index()
$build_name_index = {};
$build_names = [];
$build_list = []; # array of all build records
$build_name_index = {};
$ignore_builds = {};
$build_name_names = [];
$name_count = 0;
# Frome get_build_time_index()
$build_time_index = {};
$build_time_times = [];
$mindate_time_count = 0; # time_count that corresponds to the mindate
$time_count = 0;
$mindate_time_count = 0; # time_count that corresponds to the mindate
$build_table = [];
$who_list = [];
$who_list2 = [];
@note_array = ();
# Yeah, more globals.
$bloaty_by_log = {};
$bloaty_min_leaks = 0;
$bloaty_min_bloat = 0;
$bloat_by_log = {};
$minLeaks = 0;
$minBloat = 0;
$gzip = '/usr/local/bin/gzip';
#$body_tag = "<BODY TEXT=#000000 BGCOLOR=#8080C0 LINK=#FFFFFF VLINK=#800080 ALINK=#FFFF00>";
#$body_tag = "<BODY TEXT=#000000 BGCOLOR=#FFFFC0 LINK=#0000FF VLINK=#800080 ALINK=#FF00FF>";
if( $ENV{'USERNAME'} eq 'ltabb' ){
$gzip = 'gzip';
}
else {
$gzip = '/usr/local/bin/gzip';
}
$data_dir='data';
$lock_count = 0;
1;
sub lock{
#if( $lock_count == 0 ){
# print "locking $tree/LOCKFILE.lck\n";
# open( LOCKFILE_LOCK, ">$tree/LOCKFILE.lck" );
# flock( LOCKFILE_LOCK, 2 );
#}
#$lock_count++;
}
sub unlock{
#$lock_count--;
#if( $lock_count == 0 ){
# flock( LOCKFILE_LOCK, 8 );
# close( LOCKFILE_LOCK );
#}
}
sub print_time {
@ -103,48 +120,142 @@ sub value_encode {
}
sub tb_load_data {
sub load_data {
$tree2 = $form{'tree2'};
if( $tree2 ne '' ){
require "$tree2/treedata.pl";
if( -r "$tree2/ignorebuilds.pl" ){
require "$tree2/ignorebuilds.pl";
}
$td2 = {};
$td2->{name} = $tree2;
$td2->{cvs_module} = $cvs_module;
$td2->{cvs_branch} = $cvs_branch;
$td2->{num} = 1;
$td2->{ignore_builds} = $ignore_builds;
if( $cvs_root eq '' ){
$cvs_root = '/m/src';
}
$td2->{cvs_root} = $cvs_root;
$tree = $form{'tree'};
require "$tree/treedata.pl";
if( $cvs_root eq '' ){
$cvs_root = '/m/src';
}
}
$tree = $form{'tree'};
return undef unless $tree;
return unless $tree;
#die "the 'tree' parameter must be provided\n" unless $tree;
require "$tree/treedata.pl" if -r "$tree/treedata.pl";
if ( -r "$tree/treedata.pl" ) {
require "$tree/treedata.pl";
}
$ignore_builds = {};
require "$tree/ignorebuilds.pl" if -r "$tree/ignorebuilds.pl";
if( -r "$tree/ignorebuilds.pl" ){
require "$tree/ignorebuilds.pl";
}
$td = {};
$td->{name} = $tree;
$td->{num} = 0;
$td->{cvs_module} = $cvs_module;
$td->{cvs_branch} = $cvs_branch;
$td->{ignore_builds} = $ignore_builds;
$cvs_root = '/m/src' if $cvs_root eq '';
$td->{cvs_root} = $cvs_root;
$td1 = {};
$td1->{name} = $tree;
$td1->{num} = 0;
$td1->{cvs_module} = $cvs_module;
$td1->{cvs_branch} = $cvs_branch;
$td1->{ignore_builds} = $ignore_builds;
if( $cvs_root eq '' ){
$cvs_root = '/m/src';
}
$td1->{cvs_root} = $cvs_root;
$build_list = &load_buildlog($td);
&lock;
&load_buildlog;
&unlock;
&get_build_name_index($build_list);
&get_build_time_index($build_list);
&get_build_name_index;
&get_build_time_index;
&load_who($td, $who_list);
&load_who($who_list, $td1);
if( $tree2 ne '' ){
&load_who($who_list2, $td2);
}
&make_build_table($td, $build_list);
&make_build_table;
($bloaty_min_leaks, $bloaty_min_bloat) = load_bloaty($td);
return $td;
($minLeaks, $minBloat) = load_bloat($td1);
}
sub tb_loadquickparseinfo {
my ($tree, $build, $times, $includeStatusOfBuilding) = (@_);
local $_;
sub load_buildlog {
my $mailtime, $buildtime, $buildname, $errorparser;
my $buildstatus, $logfile,$binaryname;
my $buildrec, @treelist, $t;
$maxdate = time;
require "$tree/ignorebuilds.pl" if -r "$tree/ignorebuilds.pl";
if (not defined $maxdate) {
$maxdate = time();
}
if (not defined $mindate) {
$mindate = $maxdate - 24*60*60;
}
if ($tree2 ne '') {
@treelist = ($td1, $td2);
}
else {
@treelist = ($td1);
}
for $t (@treelist) {
use Backwards;
my ($bw) = Backwards->new("$t->{name}/build.dat") or die;
my $tooearly = 0;
while( $_ = $bw->readline ) {
chomp;
($mailtime, $buildtime, $buildname,
$errorparser, $buildstatus, $logfile, $binaryname) = split /\|/;
#$buildtime -= $buildtime % 60; # Round to minute
# Ignore stuff in the future.
next if $buildtime > $maxdate;
# Ignore stuff in the past (but get a 2 hours of extra data)
if ($buildtime < $mindate - 2*60*60) {
# Occasionally, a build might show up with a bogus time. So,
# we won't judge ourselves as having hit the end until we
# hit a full 20 lines in a row that are too early.
last if $tooearly++ > 20;
next;
}
$tooearly = 0;
$buildrec = {
mailtime => $mailtime,
buildtime => $buildtime,
buildname => ($tree2 ne '' ? $t->{name} . ' ' : '' ) . $buildname,
errorparser => $errorparser,
buildstatus => $buildstatus,
logfile => $logfile,
binaryname => $binaryname,
td => $t
};
if ($form{noignore} or not $t->{ignore_builds}->{$buildname}) {
push @{$build_list}, $buildrec;
}
}
}
}
sub loadquickparseinfo {
my ($tree, $build, $times) = (@_);
do "$tree/ignorebuilds.pl";
my $bw = Backwards->new("$tree/build.dat") or die;
use Backwards;
my ($bw) = Backwards->new("$form{tree}/build.dat") or die;
my $latest_time = 0;
my $tooearly = 0;
@ -152,8 +263,7 @@ sub tb_loadquickparseinfo {
chop;
my ($buildtime, $buildname, $buildstatus) = (split /\|/)[1,2,4];
if ($includeStatusOfBuilding or
$buildstatus =~ /^success|busted|testfailed$/) {
if ($buildstatus =~ /^success|busted|testfailed$/) {
# Ignore stuff in the future.
next if $buildtime > $maxdate;
@ -180,28 +290,240 @@ sub tb_loadquickparseinfo {
}
}
sub tb_last_status {
my ($build_index) = @_;
# Load data about who checked in when
# File format: <build_time>|<email_address>
#
sub load_who {
my ($who_list, $treedata) = @_;
local $_;
open(WHOLOG, "<$treedata->{name}/who.dat");
while (<WHOLOG>) {
chomp;
my ($checkin_time, $email) = split /\|/;
for (my $tt=0; $tt < $time_count; $tt++) {
my $br = $build_table->[$tt][$build_index];
next unless defined $br and $br->{buildstatus};
# Find the time slice where this checkin belongs.
for (my $ii = $time_count; $ii > 0; $ii--) {
if ($checkin_time <= $build_time_times->[$ii]) {
$who_list->[$ii+1]->{$email} = 1;
last;
}
}
}
# Ignore the last one
#
if ($time_count > 0) {
$who_list->[$time_count] = {};
}
}
# Load data about code bloat
# File format: <build_time>|<build_name>|<leak_delta>|<bloat_delta>
#
sub load_bloat {
my ($treedata) = @_;
local $_;
open(BLOATLOG, "<$treedata->{name}/bloat.dat");
my $leaksList = [];
my $bloatList = [];
my $index = 0;
my $listMax = 5; # only take the minimum over the last few entries
while (<BLOATLOG>) {
chomp;
my ($logfile, $leaks, $bloat) = split /\|/;
$bloat_by_log->{$logfile} = [ $leaks, $bloat ];
$leaksList[$index] = $leaks;
$bloatList[$index] = $bloat;
$index = ($index + 1) % $listMax;
}
my $leaksMin = 9999999999999;
my $bloatMin = 9999999999999;
for ($index = 0; $index < $listMax; $index++) {
print "min: $leaksList[$index] $bloatList[$index]\n";
if ($leaksList[$index] < $leaksMin) {
$leaksMin = $leaksList[$index];
}
if ($bloatList[$index] < $bloatMin) {
$bloatMin = $bloatList[$index];
}
}
return ($leaksMin, $bloatMin);
}
sub get_build_name_index {
my $i,$br;
# Get all the unique build names.
#
foreach $br (@{$build_list}) {
$build_name_index->{$br->{buildname}} = 1;
}
$i = 1;
foreach $n (sort keys (%{$build_name_index})) {
$build_name_names->[$i] = $n;
$i++;
}
$name_count = @{$build_name_names}-1;
# Update the map so it points to the right index
#
for ($i=1; $i < $name_count+1; $i++) {
$build_name_index->{$build_name_names->[$i]} = $i;
}
}
sub get_build_time_index {
my $i,$br;
# Get all the unique build names.
#
foreach $br (@{$build_list}) {
$build_time_index->{$br->{buildtime}} = 1;
}
$i = 1;
foreach $n (sort {$b <=> $a} keys (%{$build_time_index})) {
$build_time_times->[$i] = $n;
$mindate_time_count = $i if $n >= $mindate;
$i++;
}
$time_count = @{$build_time_times}-1;
# Update the map so it points to the right index
#
for ($i=1; $i < $time_count+1; $i++) {
$build_time_index->{$build_time_times->[$i]} = $i;
}
#for $i (@{$build_time_times}) {
# print $i . "\n";
#}
#while( ($k,$v) = each(%{$build_time_index})) {
# print "$k=$v\n";
#}
}
sub make_build_table {
my $i,$ti,$bi,$ti1,$br;
# Create the build table
#
for ($i=1; $i <= $time_count; $i++){
$build_table->[$i] = [];
}
# Populate the build table with build data
#
foreach $br (reverse @{$build_list}) {
$ti = $build_time_index->{$br->{buildtime}};
$bi = $build_name_index->{$br->{buildname}};
$build_table->[$ti][$bi] = $br;
}
&load_notes;
for ($bi = $name_count; $bi > 0; $bi--) {
for ($ti = $time_count; $ti > 0; $ti--) {
if (defined($br = $build_table->[$ti][$bi])
and not defined($br->{rowspan})) {
# If the cell immediately after us is defined, then we
# can have a previousbuildtime.
if (defined($br1 = $build_table->[$ti+1][$bi])) {
$br->{previousbuildtime} = $br1->{buildtime};
}
$ti1 = $ti-1;
while ($ti1 > 0 and not defined($build_table->[$ti1][$bi])) {
$build_table->[$ti1][$bi] = -1;
$ti1--;
}
$br->{rowspan} = $ti - $ti1;
if ($br->{rowspan} != 1) {
$build_table->[$ti1+1][$bi] = $br;
$build_table->[$ti][$bi] = -1;
}
}
}
}
}
sub load_notes {
if ($tree2 ne '') {
@treelist = ($td1, $td2);
}
else {
@treelist = ($td1);
}
foreach $t (@treelist) {
open(NOTES,"<$t->{name}/notes.txt")
or print "<h2>warning: Couldn't open $t->{name}/notes.txt </h2>\n";
while (<NOTES>) {
chop;
($nbuildtime,$nbuildname,$nwho,$nnow,$nenc_note) = split /\|/;
$nbuildname = "$t->{name} $nbuildname" if $tree2 ne '';
$ti = $build_time_index->{$nbuildtime};
$bi = $build_name_index->{$nbuildname};
#print "[ti = $ti][bi=$bi][buildname='$nbuildname' $_<br>";
if ($ti != 0 and $bi != 0) {
$build_table->[$ti][$bi]->{hasnote} = 1;
if (not defined($build_table->[$ti][$bi]->{noteid})) {
$build_table->[$ti][$bi]->{noteid} = (0+@note_array);
}
$noteid = $build_table->[$ti][$bi]->{noteid};
$now_str = &print_time($nnow);
$note = &url_decode($nenc_note);
$note_array[$noteid] = "<pre>\n[<b><a href=mailto:$nwho>"
."$nwho</a> - $now_str</b>]\n$note\n</pre>"
.$note_array[$noteid];
}
}
close(NOTES);
}
}
sub last_success_time {
my ($row) = @_;
for (my $tt=1; $tt <= $time_count; $tt++) {
my $br = $build_table->[$tt][$row];
next unless defined $br;
next unless $br->{buildstatus} eq 'success';
return $build_time_times->[$tt + $br->{rowspan} ];
}
return 0;
}
sub last_status {
my ($row) = @_;
for (my $tt=1; $tt <= $time_count; $tt++) {
my $br = $build_table->[$tt][$row];
next unless defined $br;
next unless $br->{buildstatus} =~ /^(success|busted|testfailed)$/;
return $br->{buildstatus};
}
return 'building';
}
sub tb_check_password {
if ($form{password} eq '' and defined $cookie_jar{tinderbox_password}) {
$form{password} = $cookie_jar{tinderbox_password};
sub check_password {
if ($form{password} eq '') {
if (defined $cookie_jar{tinderbox_password}) {
$form{password} = $cookie_jar{tinderbox_password};
}
}
my $correct = '';
if (open(REAL, '<data/passwd')) {
$correct = <REAL>;
close REAL;
$correct =~ s/\s+$//; # Strip trailing whitespace.
}
if (open(REAL, '<data/passwd')) {
$correct = <REAL>;
close REAL;
$correct =~ s/\s+$//; # Strip trailing whitespace.
}
$form{password} =~ s/\s+$//; # Strip trailing whitespace.
if ($form{password} ne '') {
open(TRAPDOOR, "../bonsai/data/trapdoor $form{'password'} |")
@ -249,19 +571,14 @@ sub tb_check_password {
exit;
}
sub tb_find_build_record {
sub find_build_record {
my ($tree, $logfile) = @_;
local $_;
my $log_entry = '';
my ($bw) = Backwards->new("$tree/build.dat") or die;
while( $_ = $bw->readline ) {
$log_entry = $_ if /$logfile/;
}
my $log_entry = `grep $logfile $tree/build.dat`;
chomp($log_entry);
my ($mailtime, $buildtime, $buildname, $errorparser,
$buildstatus, undef, $binaryname) = split /\|/, $log_entry;
$buildstatus, $logfile, $binaryname) = split /\|/, $log_entry;
$buildrec = {
mailtime => $mailtime,
@ -275,243 +592,3 @@ sub tb_find_build_record {
};
return $buildrec;
}
sub tb_build_static {
# Build tinderbox static pages
$ENV{QUERY_STRING}="tree=$tree&static=1";
$ENV{REQUEST_METHOD}="GET";
system './showbuilds.cgi >/dev/null&';
}
# end of public functions
#============================================================
sub load_buildlog {
my ($treedata) = $_[0];
# In general you always want to make "$_" a local
# if it is used. That way it is restored upon return.
local $_;
my $build_list = [];
if (not defined $maxdate) {
$maxdate = time();
}
if (not defined $mindate) {
$mindate = $maxdate - 24*60*60;
}
my ($bw) = Backwards->new("$treedata->{name}/build.dat") or die;
my $tooearly = 0;
while( $_ = $bw->readline ) {
chomp;
my ($mailtime, $buildtime, $buildname,
$errorparser, $buildstatus, $logfile, $binaryname) = split /\|/;
# Ignore stuff in the future.
next if $buildtime > $maxdate;
# Ignore stuff in the past (but get a 2 hours of extra data)
if ($buildtime < $mindate - 2*60*60) {
# Occasionally, a build might show up with a bogus time. So,
# we won't judge ourselves as having hit the end until we
# hit a full 20 lines in a row that are too early.
last if $tooearly++ > 20;
next;
}
$tooearly = 0;
if ($form{noignore} or not $treedata->{ignore_builds}->{$buildname}) {
my $buildrec = {
mailtime => $mailtime,
buildtime => $buildtime,
buildname => $buildname,
errorparser => $errorparser,
buildstatus => $buildstatus,
logfile => $logfile,
binaryname => $binaryname,
td => $treedata
};
push @{$build_list}, $buildrec;
}
}
return $build_list;
}
# Load data about who checked in when
# File format: <build_time>|<email_address>
#
sub load_who {
my ($treedata, $who_list) = @_;
local $_;
open(WHOLOG, "<$treedata->{name}/who.dat");
while (<WHOLOG>) {
chomp;
my ($checkin_time, $email) = split /\|/;
# Find the time slice where this checkin belongs.
for (my $ii = $time_count - 1; $ii >= 0; $ii--) {
if ($checkin_time <= $build_time_times->[$ii]) {
$who_list->[$ii+1]->{$email} = 1;
last;
}
}
}
# Ignore the last one
#
#if ($time_count > 0) {
# $who_list->[$time_count] = {};
#}
}
# Load data about code bloat
# File format: <build_time>|<build_name>|<leak_delta>|<bloat_delta>
#
sub load_bloaty {
my $treedata = $_[0];
local $_;
open(BLOATLOG, "<$treedata->{name}/bloat.dat");
my $leaks_list = [];
my $bloat_list = [];
my $index = 0;
my $list_max = 5; # only take the minimum over the last few entries
while (<BLOATLOG>) {
chomp;
my ($logfile, $leaks, $bloat) = split /\|/;
$bloaty_by_log->{$logfile} = [ $leaks, $bloat ];
$leaks_list[$index] = $leaks;
$bloat_list[$index] = $bloat;
$index++;
$index = 0 unless $index < $list_max;
}
my $leaks_min = $leaks_list[0];
my $bloat_min = $bloat_list[0];
for ($index = 1; $index < $list_max; $index++) {
if ($leaks_list[$index] < $leaks_min) {
$leaks_min = $leaks_list[$index];
}
if ($bloat_list[$index] < $bloat_min) {
$bloat_min = $bloat_list[$index];
}
}
return ($leaks_min, $bloat_min);
}
sub get_build_name_index {
my ($build_list) = @_;
# Get all the unique build names.
#
foreach my $build_record (@{$build_list}) {
$build_name_index->{$build_record->{buildname}} = 1;
}
my $ii = 0;
foreach my $name (sort keys %{$build_name_index}) {
$build_names->[$ii] = $name;
$build_name_index->{$name} = $ii;
$ii++;
}
$name_count = $#{$build_names} + 1;
}
sub get_build_time_index {
my ($build_list) = @_;
# Get all the unique build names.
#
foreach my $br (@{$build_list}) {
$build_time_index->{$br->{buildtime}} = 1;
}
my $ii = 0;
foreach my $time (sort {$b <=> $a} keys %{$build_time_index}) {
$build_time_times->[$ii] = $time;
$build_time_index->{$time} = $ii;
$mindate_time_count = $ii if $time >= $mindate;
$ii++;
}
$time_count = $#{$build_time_times} + 1;
}
sub make_build_table {
my ($treedata, $build_list) = @_;
my ($ti, $bi, $ti1, $br);
# Create the build table
#
for (my $ii=0; $ii < $time_count; $ii++){
$build_table->[$ii] = [];
}
# Populate the build table with build data
#
foreach $br (reverse @{$build_list}) {
$ti = $build_time_index->{$br->{buildtime}};
$bi = $build_name_index->{$br->{buildname}};
$build_table->[$ti][$bi] = $br;
}
&load_notes($treedata);
for ($bi = $name_count - 1; $bi >= 0; $bi--) {
for ($ti = $time_count - 1; $ti >= 0; $ti--) {
if (defined($br = $build_table->[$ti][$bi])
and not defined($br->{rowspan})) {
# If the cell immediately after us is defined, then we
# can have a previousbuildtime.
if (defined($br1 = $build_table->[$ti+1][$bi])) {
$br->{previousbuildtime} = $br1->{buildtime};
}
$ti1 = $ti-1;
while ($ti1 >= 0 and not defined $build_table->[$ti1][$bi]) {
$build_table->[$ti1][$bi] = -1;
$ti1--;
}
$br->{rowspan} = $ti - $ti1;
unless ($br->{rowspan} == 1) {
$build_table->[$ti1+1][$bi] = $br;
$build_table->[$ti][$bi] = -1;
}
}
}
}
}
sub load_notes {
my $treedata = $_[0];
open(NOTES,"<$treedata->{name}/notes.txt")
or print "<h2>warning: Couldn't open $treedata->{name}/notes.txt </h2>\n";
while (<NOTES>) {
chop;
my ($nbuildtime,$nbuildname,$nwho,$nnow,$nenc_note) = split /\|/;
my $ti = $build_time_index->{$nbuildtime};
my $bi = $build_name_index->{$nbuildname};
if (defined $ti and defined $bi) {
$build_table->[$ti][$bi]->{hasnote} = 1;
unless (defined $build_table->[$ti][$bi]->{noteid}) {
$build_table->[$ti][$bi]->{noteid} = $#note_array + 1;
}
$noteid = $build_table->[$ti][$bi]->{noteid};
$now_str = &print_time($nnow);
$note = &url_decode($nenc_note);
$note_array[$noteid] = '' unless $note_array[$noteid];
$note_array[$noteid] = "<pre>\n[<b><a href=mailto:$nwho>"
."$nwho</a> - $now_str</b>]\n$note\n</pre>"
.$note_array[$noteid];
}
}
close NOTES;
}