зеркало из https://github.com/mozilla/pjs.git
Somethings not working. Backup
This commit is contained in:
Родитель
28183cec5b
Коммит
12bc6ea86c
|
@ -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/^.* //;
|
||||
} 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/^.* //;
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче