#!/usr/local/bin/perl # # Copyright (c) 2002-2004 Eric Wallengren # This file is part of the Continuous Automated Build and Integration # Environment (CABIE) # # CABIE is distributed under the terms of the GNU General Public # License version 2 or any later version. See the file COPYING for copying # permission or http://www.gnu.org. # # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR # IMPLIED, without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. ANY USE IS AT YOUR OWN RISK. # # Permission to modify the code and to distribute modified code is granted, # provided the above notices are retained, and a notice that the code was # modified is included with the above copyright notice. # use Getopt::Long; use File::Basename; use English; use Sys::Hostname; my $hostname = hostname(); BEGIN {push @INC, "./lib";} require "$hostname.pm"; my $config = new $hostname; my $logo = $config->LOGOICON; my $prog = basename( $PROGRAM_NAME ); use strict; use vars qw( $opt_help $opt_infile $opt_outfile $opt_errorfile $opt_refresh $opt_binary $opt_server $opt_port $opt_job ); # ------------------------------------------------------------------ my( @whenlist ) = ( "build", "package" ); my( $output ) = ""; my( $num_sections ) = 0; my( $num_warnings ) = 0; my( $num_errors ) = 0; my( @error_list ); my( %section_link ); my( %warn_link ); my( %error_link ); my( $module_order ); my( %elapsed_time ); my( %products ); my( %ignored ); my( $image_platform ); my( $image_product ); # ------------------------------------------------------------------ # Load the list of error strings from a file. sub loadErrorList { my( $error_file ) = @_; open( ERRORFILE, "<$error_file" ) or die "Can't open $error_file"; @error_list = ; close( ERRORFILE ); chomp @error_list; } # ------------------------------------------------------------------ # Return 1 if an error string is detected in the input line. sub hasError { my( $line ) = @_; my( $err ); foreach $err ( @error_list ) { if ( index( $line, $err ) > -1 ) { return 1; } } return 0; } # ------------------------------------------------------------------ # Escape HTML characters. "<" -> < ">" -> > "&" -> & sub esc { my( $text ) = @_; $text =~ s/&/&/g; $text =~ s//>/g; return $text; } # ------------------------------------------------------------------ sub processLog { my( $in_header ) = 0; my( $when ); my( %seen ); my( %seen_product ); my( $who ); my( @contents ); my( @tmpcontents ); my( $line ); while ( ) { if ( /^\s*(\[echo\])?\s*#-----------------/ ) { if ( ! $in_header ) { $output = $output . "\n" . "

\n" . "
\n" .
                         esc( $_ );

                $in_header = 1;
            }
            else
            {
                $in_header = 0;

                $output = $output .
                         esc( $_ ) .
                         "
\n" . "

\n" . "
\n";
            }
        }
        elsif ( /^\s*\[create-distribution\]\s*creating.*image/ )
        {
            my( @words ) = split( " " );

            $image_platform = $words[ $#words - 2 ] eq "creating"
                            ? "all"
                            : $words[ $#words - 2 ];

            $image_product = $words[ $#words - 1 ];

            $num_sections++;

            $output = $output .
                     "
\n" . "

\n" . "
$_
\n" . "

\n" . "
\n";

            $who = "$image_product-$image_platform";
            $section_link{ $who, "image" } = $num_sections;

            if ( ! $seen_product{ $who } )
            {
                $seen_product{ $who } = 1;
                $products{ $image_product } .= " " . $image_platform;
            }
        }
        elsif ( /^\s*\[create-distribution\]\s*elapsed staging time:/ )
        {
            my( @words ) = split( " " );
            $output = $output . esc( $_ );
            $elapsed_time{ $who, "image" } = $words[ $#words - 1 ];
        }
        elsif ( /^\s*\[create-distribution\]\s*elapsed iso time:/ )
        {
            my( @words ) = split( " " );
            $output = $output . esc( $_ );
            $elapsed_time{ $who, "iso" } = $words[ $#words - 1 ];
        }
        elsif ( $in_header eq 1 )
        {
            my( $ignore );
            my( @words ) = split( " " );

            chomp;

            $num_sections++;
            $output = $output . "" . esc( $_ ) .
                                "\n";

            $ignore = $words[ $#words - 2 ] eq "Ignore";

            if ( $words[ $#words ] eq "module" )
            {
                $when = "build";
            }
            elsif ( $words[ $#words ] eq "package" )
            {
                $when = "package";
            }
            else
            {
                $when = "?";
            }

            if ( $when ne "?" )
            {
                my( $module ) = $words[ $#words - 1 ];

                $who = $module;
                $section_link{ $who, $when } = $num_sections;
                $ignored{ $who, $when } = $ignore;

                if ( ! $seen{ $module } )
                {
                    $seen{ $module } = 1;
                    $module_order = "$module_order $module";
                }
            }
        }
        else
        {
            if ( hasError( $_ ) )
            {
                $num_errors++;
                chomp;
                $output = $output .
                          "
\n" . "
\n" .
                          "\n" .
                          "" . esc( $_ ) .
                          "\n" .
                          "\n" .
                          "
\n" . "
\n";

                $error_link{ $who, $when } .= " $num_errors";
            }
            elsif ( /warning/i )
            {
                $num_warnings++;
                chomp;
                $output = $output .
                          "
\n" . "
\n" .
                          "\n" .
                          "" . esc( $_ ) .
                          "\n" .
                          "\n" .
                          "
\n" . "
\n";

                $warn_link{ $who, $when } .= " $num_warnings";
            }
            elsif ( /^\s*(\[echo\])?\s*# .* time: [0-9.:]+ sec/ )
            {
                my( @words ) = split( " " );
                my( $secs ) = $words[ $#words - 1 ];
                my( @t ) = split( ":", $secs );

                if ( $#t > 0 )
                {
                    $secs = $t[ 0 ] * 60 + $t[ 1 ];
                }

                $output = $output . esc( $_ );

                $elapsed_time{ $who, $when } = $secs;
            }
            else
            {
                $output = $output . esc( $_ );
            }
        }
    }

    close( BUILDLOG );
}

# ------------------------------------------------------------------
sub outputHtml
{

    print HTML "\n";
    print HTML "\n";

    if ( $opt_refresh > 0 )
    {
        print HTML "    \n";
    }

    print HTML "    \n";
    print HTML "\n";
    print HTML "\n";
    print HTML "";
    print HTML "\"LOGO\"\n";
    print HTML "
"; print HTML "
"; outputNavigation(); outputModuleTable(); print HTML "

\n"; outputCdTable(); print HTML "

\n";
    print HTML $output;
    print HTML "
\n"; outputNavigation(); print HTML "
"; print HTML "\n"; close( HTML ); } # ------------------------------------------------------------------ sub outputNavigation { print HTML "\n"; } # ------------------------------------------------------------------ sub outputModuleTable { my( $when ); my( $module ); print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML " "; foreach $when ( @whenlist ) { print HTML " \n"; } print HTML "\n"; print HTML "\n"; foreach $module ( split( " ", $module_order ) ) { print HTML "\n"; print HTML " \n"; foreach $when ( @whenlist ) { my( $status ); if ( $elapsed_time{ $module, $when } ) { $status = "success"; } else { $status = $ignored{ $module, $when } ? "n/a" : "working"; } print HTML " \n"; } print HTML "
module\n"; print HTML " $when
$module"; outputStatusCell( $module, $when, $status ); outputTimeCell( $module, $when ); } print HTML "
\n"; } # ------------------------------------------------------------------ sub outputCdTable { my( $when ); my( $key ); my( $platform ); if ( %products ) { print HTML "\n"; print HTML "\n"; print HTML "\n"; print HTML " "; print HTML " "; print HTML " \n"; print HTML " \n"; print HTML " \n"; print HTML "\n"; print HTML "\n"; for $key ( sort ( keys %products ) ) { my( @platforms ) = split( " ", $products{ $key } ); my( $first ) = 1; my( $span ) = $#platforms + 1; print HTML " \n"; print HTML " \n"; print HTML " \n"; foreach $platform ( sort @platforms ) { my( $who ) = "$key-$platform"; if ( ! $first ) { print HTML " \n"; } print HTML " \n"; print HTML " \n"; $first = 0; } } print HTML "
productplatform\n"; print HTML " statusimageiso
$key
$platform"; outputStatusCell( $who, "image", "success" ); outputTimeCell( $who, "image" ); outputTimeCell( $who, "iso" ); print HTML "
\n"; } } # ------------------------------------------------------------------ sub outputStatusCell { my( $who, $when, $status ) = @_; my( $section ) = $section_link{ $who, $when }; my( $warn ) = $warn_link{ $who, $when }; my( $error ) = $error_link{ $who, $when }; my( $num ); # Add all error links if ( $error ) { print HTML " "; print HTML "\n errors:\n"; foreach $num ( split( " ", $error ) ) { print HTML "  $num\n"; } print HTML " "; } # Add all warning links if ( $warn ) { if ( $error ) { print HTML "
\n"; } else { print HTML " "; } print HTML "\n warnings:\n"; foreach $num ( split( " ", $warn ) ) { print HTML "  $num\n"; } print HTML " "; } # If no error or warnings, add section link if applicable if ( ! $error && ! $warn ) { if ( $section ) { if ( $status eq "working" ) { print HTML " "; } else { print HTML " "; } print HTML "$status"; } else { print HTML " "; print HTML "        " . "       "; } } print HTML "\n"; } # ------------------------------------------------------------------ sub outputTimeCell { my( $who, $when ) = @_; my( $time ) = $elapsed_time{ $who, $when }; if ( $time ) { my( $min ) = 0; my( $sec ) = 0; if ( $time >= 60 ) { $min = int( $time / 60 ); $sec = $time % 60; } else { $sec = $time; } $time = sprintf( "%d' %02d\"", $min, $sec ); } if ( ! $time ) { $time = "       "; } print HTML " $time\n"; } # ------------------------------------------------------------------ sub help { print STDERR "Usage: $prog -e error_file [options]\n"; print STDERR "\n"; print STDERR " options:\n"; print STDERR " -i log_file\n"; print STDERR " -o html_file\n"; print STDERR " -e error_file\n"; print STDERR " -S buildserver\n"; print STDERR " -P port\n"; print STDERR " -j jobname\n"; print STDERR " -b path-to-build-command\n"; print STDERR " -r meta-refresh-in-secs\n"; print STDERR "\n"; print STDERR " If neither -i nor -j is specified, stdin is used.\n"; print STDERR " If -o is not specified, stdout is used.\n"; } # ------------------------------------------------------------------ if ( ! GetOptions( "infile|i=s", "outfile|o=s", "errorfile|e=s", "refresh|r=i", "port|p=s", "server|s=s", "binary|b=s", "job|j=s", "help|h" ) ) { help(); exit 1; } if ( $opt_help ) { help(); exit 0; } #----------------------------------------------------------------------- if ( $opt_job ) { open( BUILDLOG, "$opt_binary buildlog -n $opt_job -t retail|" ) or die "Can't open $opt_job"; } elsif ( $opt_infile ) { if ( ! -f $opt_infile ) { print "Error: $prog: no such file: $opt_infile\n"; exit 1; } open( BUILDLOG, "<$opt_infile" ) or die "Can't open $opt_infile"; } else { open( BUILDLOG, "<&=STDIN" ); } #----------------------------------------------------------------------- if ( ! $opt_errorfile ) { print "Error: $prog: '-e error_file' is required\n"; help(); exit 1; } elsif ( ! -f $opt_errorfile ) { print "Error: $prog: no such file: $opt_errorfile\n"; exit 1; } else { loadErrorList( $opt_errorfile ); } #----------------------------------------------------------------------- if ( $opt_outfile ) { open( HTML, ">$opt_outfile" ) or die "Can't open $opt_outfile"; } else { open( HTML, ">&=STDOUT" ); $| = 1; } $ENV{ BLDSERVER } = "$opt_server:$opt_port"; processLog(); outputHtml();