eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' & eval 'exec perl -S $0 $argv:q' if 0; # -*- perl -*- # $Id$ # # This script checkouts ACE from CVS, updates the "clone" directory, # compiles $ACE_ROOT/ace and $ACE_ROOT/tests and finally runs # $ACE_ROOT/tests/run_tests.sh. # # If it detects any problem it send email. # # DO NOT invoke this script from your crontab, use # auto_compile_wrapper for that. # # This script requires Perl5. # # TODO: Modify the script or split it in such a way that the main copy # can be obtained either using cvs or downloading the lastest beta # from the WWW. # # The first three lines above let this script run without specifying the # full path to perl, as long as it is in the user's PATH. # Taken from perlrun man page. use File::Basename; use FileHandle; require POSIX; # This is the module we will checkout, someday someone could define a # smaller module. $MODULE='ACE_wrappers'; # This are the sub-directories (in the module) we really compile. # Find out the command name. $CMD = basename($0); $single_threaded = 0; $minimum_corba = 0; $ami = 0; $dont_update = 0; $dont_run = 0; $pre_realclean = 0; $post_realclean = 0; $report_success = 0; $debug = 0; @BUILD_LIST= (); @ARGS = (); while ($#ARGV >= 0) { if (!($ARGV[0] =~ m/-/)) { push @ARGS, $ARGV[0]; shift; } elsif ($ARGV[0] eq "-single_threaded") { $single_threaded = 1; shift; } elsif ($ARGV[0] eq "-minimum_corba") { $minimum_corba = 1; shift; } elsif ($ARGV[0] eq "-ami") { $ami =1; shift; }elsif ($ARGV[0] eq "-build_list") { shift; @BUILD_LIST = split (/,/, $ARGV[0]); shift; } elsif ($ARGV[0] eq "-dont_update") { $dont_update = 1; shift; } elsif ($ARGV[0] eq "-dont_run") { $dont_run = 1; shift; } elsif ($ARGV[0] eq "-pre_realclean") { $pre_realclean = 1; shift; } elsif ($ARGV[0] eq "-post_realclean") { $post_realclean = 1; shift; } elsif ($ARGV[0] eq "-report_success") { $report_success = 1; shift; } elsif ($ARGV[0] eq "-debug") { $debug = 1; shift; } } # Extract configuration information from command line. # TODO: Some validation and checking should be done here. $CHECKOUT = $ARGS[0]; $BUILD = $ARGS[1]; $LOGDIR = $ARGS[2]; $ADMIN = $ARGS[3]; $MAIL = "mail"; if ($#ARGS >= 4) { $MAIL = $ARGS[4]; } $ENV{'ACE_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD; $ENV{'TAO_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD . '/TAO'; # We obtain our revision to report errors. $REVISION='$Revision$ '; # When an error is found we try to die gracefully and send some email # to ADMIN. $disable_file = $LOGDIR . '/.disable'; $histfile = $LOGDIR . '/history'; $LOGBASE = POSIX::strftime("%b%d_%Y.log", localtime); $LOGFILE = $LOGDIR . '/' . $LOGBASE; $HOST = `hostname`; chop $HOST; $LOG_NAME = $HOST . "_" . $BUILD . "_" . $LOGBASE; $STATUS = "OK"; if ($debug) { print "CHECKOUT = $CHECKOUT\n"; print "BUILD = $BUILD\n"; print "LOGDIR = $LOGDIR\n"; print "ADMIN = $ADMIN\n"; print "MAIL = $MAIL\n"; print "ACE_ROOT = $ENV{ACE_ROOT}\n"; print "TAO_ROOT = $ENV{TAO_ROOT}\n"; } push @INC, $CHECKOUT . '/' . $MODULE . '/bin'; require run_all_list; if ($#BUILD_LIST == -1) { @BUILD_LIST= ('ace', 'netsvcs', 'tests', 'apps/gperf', 'TAO'); } if ($debug) { @BUILD_LIST = ('ace'); @RUN_LIST = ('TAO/tests/OctetSeq , run_test.pl'); @SINGLE_THREADED_LIST = ('TAO/tests/OctetSeq , run_test.pl'); @MINIMUM_CORBA_LIST = ('TAO/tests/OctetSeq , run_test.pl'); $ADMIN = $ENV{'LOGNAME'}; } sub mydie { unlink $disable_file; die $_ . "\n"; } sub report_errors { # First clear the lock, so the next execution works... unlink $disable_file; # Ignore errors! # Now send a summary of the errors to the ADMIN account... local $to = $ADMIN; open (MAIL, "|".$MAIL.' -s "[AUTO_COMPILE] '.$BUILD.'" '.$to) || mydie "Cannot open mail pipe for: $_\n"; print MAIL 'The following message is brought to you by: ', "\n"; print MAIL $CMD, ' [', $REVISION, "] for $BUILD on $CHECKOUT\n\n"; local $m; foreach $m (@_) { print MAIL $m, "\n"; } print MAIL "\nPlease check the following log for more info:\n\n"; print MAIL 'http://www.cs.wustl.edu/~bugzilla/auto_compile_logs/', $LOG_NAME, "\n\n"; close (MAIL); # Ignore errors.... # Now send the complete log to bugzilla... local $bugs = 'bugzilla'.'@cs.wustl.edu'; open (MAIL, "|".$MAIL.' -s AUTO_COMPILE_LOG='.$LOG_NAME.' '.$bugs) || mydie "Cannot open mail pipe for: $LOG_NAME\n"; print MAIL 'This is the log for: ', "\n"; print MAIL $CMD, ' [', $REVISION, "] for $BUILD on $CHECKOUT\n"; print MAIL "\n================================================================\n"; if (open (THELOG, "$LOGFILE")) { while () { print MAIL $_; } close (THELOG); } close (MAIL); # Ignore errors.... } ### MAIN FUNCTION if (-f $disable_file) { print 'The following message is brought to you by: ', "\n"; print $CMD, ' [', $REVISION, "] for $BUILD on $CHECKOUT\n"; print "DISABLED\n"; exit 0; } open (DISABLE, '>' . $disable_file) || die "cannot open disable file"; print DISABLE "auto_compile <$date> is running\n"; close (DISABLE) || die "cannot close disable file"; open(HIST, '>>' . $histfile) # Do not use 'mydie' to report the problem, it tries to remove the # disable file || mydie "cannot open history file \"$histfile\"\n"; $date = localtime; print HIST $CMD, ': running at ', $date, ' '; open(LOG, '>' . $LOGFILE) || mydie "cannot open log file"; LOG->autoflush (); # The following lines are useful when debugging the script or wrapper. # print LOG $CHECKOUT, " ", $BUILD, " ", $LOGDIR, " ", $ADMIN, "\n"; #while (($key,$value) = each %ENV) { # print LOG $key, " = ", $value, "\n"; #} chdir($CHECKOUT) || mydie "Cannot chdir to $CHECKOUT"; if ($dont_update == 0) { $date = localtime; print LOG "$CMD: starting checkout at ", $date, "\n"; open(CVS, "cvs -q checkout -P $MODULE 2>&1 |") || mydie "cannot start checkout of $MODULE"; $conflicts = 0; while () { if (m/^C /) { $conflicts = 1; } print LOG $_; } close(CVS) || mydie "error while checking out $MODULE"; $date = localtime; print LOG "$CMD: checkout finished at ", $date, "\n"; if ($conflicts != 0) { mydie "conflicts on checkout"; } } chdir($MODULE) || mydie "cannot chdir to $MODULE"; open (CHLOG, "ChangeLog") || mydie "cannot open Changelog"; $_ = ; chop; print LOG "ACE ChangeLogTag:", $_, "\n"; close (CHLOG); open (CHLOG, "TAO/ChangeLog") || mydie "cannot open TAO/Changelog"; $_ = ; chop; print LOG "TAO ChangeLogTag:", $_, "\n"; close (CHLOG); $date = localtime; print LOG "$CMD: starting clone at ", $date, "\n"; open(CLONE, "perl bin/create_ace_build -a -v $BUILD 2>&1 |") || mydie "cannot clone directory"; while() { print LOG $_; } close(CLONE) || mydie "error while cloning ACE_ROOT"; $date = localtime; print LOG "$CMD: clone finished at ", $date, "\n"; chdir('build/' . $BUILD) || mydie "cannot chdir to $BUILD"; @failures = (); if ($pre_realclean) { foreach $i (@BUILD_LIST) { $date = localtime; print LOG "$CMD: =============================================\n"; print LOG "$CMD: make realclean in $i started at ", $date, "\n"; open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |") || mydie "cannot start make in $i"; while () { # Ignore errors.... } if (close(MAKE) == 0) { push @failures, "errors while cleaning $i"; } $date = localtime; print LOG "$CMD: make realclean in $i finished at ", $date, "\n"; print LOG "$CMD: =============================================\n\n"; } } $MAKEFLAGS .= ""; foreach $i (@BUILD_LIST) { $date = localtime; print LOG "$CMD: =============================================\n"; print LOG "$CMD: make for $i started at ", $date, "\n"; open(MAKE, "make -k $MAKEFLAGS -C $i 2>&1 |") || mydie "cannot start make for $i"; local $current_dir = $i; local $last_error = ""; while () { chop; if ($^O eq 'hpux' && m/^Warning:[ \t]+[0-9]+ future errors were detected/) { next; } print LOG $_, "\n"; if (m/^make(\[[0-9]+\])?: Entering directory /) { s/^make(\[[0-9]+\])?: Entering directory //; s%^$ENV{'ACE_ROOT'}/%%; $current_dir = $_; } if (m/error:/i || m/error /i || m/^make(\[[0-9]+\])?: \*\*\*/) { if ($last_error ne $current_dir || STATUS eq "COMPILATION WARNING") { $STATUS = "COMPILATION ERROR"; push @failures, "Error while compiling in $current_dir \n"; $last_error = $current_dir; } } if (m/warning:/i || m/warning /i) { if ($last_error ne $current_dir) { if ($STATUS eq "OK") { $STATUS = "COMPILATION WARNING"; } push @failures, "Warning while compiling in $current_dir\n"; $last_error = $current_dir; } } } if (close(MAKE) == 0) { push @failures, "errors while running make in $i"; } $date = localtime; print LOG "$CMD: make for $i finished at ", $date, "\n"; print LOG "$CMD: =============================================\n\n"; } if ($dont_run == 0) { @LIST = @RUN_LIST; if ($single_threaded) { @LIST = @SINGLE_THREADED_LIST; } elsif ($minimum_corba) { @LIST = @MINIMUM_CORBA_LIST; } elsif ($ami) { @LIST = @AMI_CORBA_LIST; } foreach $i (@LIST) { local @test_info = split (/\ \,\ /, $i); local $directory = $test_info[0]; local $program = $test_info[1]; $date = localtime; print LOG "$CMD: =============================================\n"; print LOG "$CMD: running $program in $directory at ", $date, "\n"; local $subdir = $CHECKOUT .'/'. $MODULE .'/build/'. $BUILD .'/'. $directory; chdir ($subdir) || mydie "cannot chdir to $subdir"; $run_error = 0; if (open(RUN, "perl $program 2>&1 |") == 0) { push @failures, "cannot run $program in $directory"; next; } while () { print LOG $_; if (m/Error/ || m/ERROR/ || m/FAILED/ || m/EXCEPTION/ || m/pure virtual /i) { if ($STATUS eq "OK") { $STATUS = "RUNTIME ERROR"; } $run_error = 1; } } if (close(RUN) == 0) { if ($STATUS eq "OK") { $STATUS = "RUNTIME ERROR"; } push @failures, "Error when closing pipe for $program in $directory"; next; } $date = localtime; print LOG "$CMD: $program finished ", $date, "\n"; if ($run_error != 0) { push @failures, "errors detected while running $program in $directory"; } } } if ($post_realclean) { foreach $i (@BUILD_LIST) { $date = localtime; print LOG "$CMD: =============================================\n"; print LOG "$CMD: make realclean in $i started at ", $date, "\n"; open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |"); while () { # Ignore errors.... } if (close(MAKE) == 0) { push @failures, "errors while cleaning $i"; } $date = localtime; print LOG "$CMD: make realclean in $i finished at ", $date, "\n"; print LOG "$CMD: =============================================\n\n"; } } if ($#failures >= 0) { report_errors @failures; } close(LOG) || mydie "cannot close LOGFILE"; print HIST "$STATUS\n"; close(HIST) || mydie "cannot close history file"; unlink $disable_file || die "cannot unlink disable file"; if ($report_success && $STATUS eq "OK") { report_errors "Congratulations: No errors or warnings detected\n"; } exit 0;