#!/usr/bin/perl -w
# automatic buildskript
# reads configuration from option -b BUILDLIST
# $Id: dassbuild_all.pl 762 2009-06-12 16:24:00Z joergs $


use strict;
use Getopt::Std;
use File::stat;
use File::Basename;

my $wert1;
my $wert2;
my $wert3;

format TABELLE =
@<<<<<<<<<<<<<<<<<< @<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$wert1, $wert2, $wert3
.


# Programmoptionen: 
#	-b 	buildlist 
#	-x 	(buildlog im seperaten xterm)
#	-d	Zielpfad um Install Source zu erzeugen

my $workdir=`pwd`;
chomp $workdir;

# Pfad, zu dem die Pfade in buildlist stehen
my $src_root="../../";   


my $BUILD_DEST_DIR="/tmp/build.$ENV{'USER'}/";
my $INSTALL_SRC_SKEL_DIR="/net/dist/data/dist/sles/8/skeleton-i386/smartclient/";

my $build = "dassbuild.sh";
our ( $opt_x, $opt_b, $opt_d );
my @ArrayofBuilds;
getopts('xb:d:');

my $skipped_last = 0;

if (!$opt_b && !$opt_d)  {
	print <<EOF
Usage:
  -b BUILDLIST
     compiles packages specified in BUILDLIST
  -d INSTALL_SRC_DEST_DIR
     creates a new install source in INSTALL_SRC_DEST_DIR
EOF
};



#
# build packages from buildlist
#

if( $opt_b ) {
(open(BUILDLIST,$opt_b)) || die "Die Buildlist $opt_b  konnte nicht gefunden werden";


while (<BUILDLIST>) #Buildlist parsen
  {
  	my $dir;
	my $arch;
	my $opt;
    next if (/^\#.*$/);
	# if (/([\w\/]+)\s*:([\/\w\-\+\.]+)\s+:((\s*\-\-\w*)*)$/)
    if (/(\S+)\s*:(\S+)\s*:(\S+)\s*$/)
      {
	($dir, $arch, $opt) = ($1, $2, $3);
	chomp ($arch);
	my @build=($dir, $arch, $opt);
	push @ArrayofBuilds, [@build];
      }
  }



print "What will be done:\n\n";
($wert1,$wert2,$wert3)= ("BUILD_DIST","BUILD_MODE","Package");
$~="TABELLE";
write;
for my $i (0 .. $#ArrayofBuilds)
  {
    ($wert1,$wert2,$wert3)= ($ArrayofBuilds[$i][1],$ArrayofBuilds[$i][2],$ArrayofBuilds[$i][0]);
    $~="TABELLE";
    write;
  }

print 'Are all options OK? (y/n)';

my $answer=<STDIN>;
chomp ($answer);
if ($answer ne "y") {die("canceled")};

$ENV{'DEST_DIR'}=$BUILD_DEST_DIR;

my $mypath;
for my $i (0 .. $#ArrayofBuilds)
  {
  print("$ArrayofBuilds[$i][0]\t\t$ArrayofBuilds[$i][1]\t\t$ArrayofBuilds[$i][2]\n");
  $mypath = $src_root.$ArrayofBuilds[$i][0];

  if( $ArrayofBuilds[$i][2] && !$skipped_last )
    {
      $ENV{'BUILD_MODE'}=$ArrayofBuilds[$i][2];
    }
  else 
    {
      $ENV{'BUILD_MODE'}="--verify";
    }
  $ENV{'BUILD_DIST'}=$ArrayofBuilds[$i][1];

  
  $_=$ArrayofBuilds[$i][0];
  print "$_ \n";
  tr/\//\_/;
  `mkdir -p $BUILD_DEST_DIR`;
  `mkdir -p $BUILD_DEST_DIR/log`;
  my $logfilename = "$BUILD_DEST_DIR/log/$_$ArrayofBuilds[$i][1].log";

  my $build_cmd="cd $mypath && $build";

  # open a xterm to display build output
  if ($opt_x)
  {
    system "xterm -T \"build log for PACKET: $mypath    ARCH:$ArrayofBuilds[$i][1] \" -e less +F $logfilename &";
    print "++++++++++++++++++++++++++++++++++++++++++\n";
  }

  # if mypath is not a directory, so it is a .src.rpm (hopefully)
  if( ! -d $mypath ) {
	my $base 	= basename($mypath);
	my $dir  	= dirname($mypath);
	# TODO: find the src.rpm with the highest version/release number
	$build_cmd	= "cd $dir && $build $base-[0-9]*rpm";
  }

  print "++++++++++++++++++++++++++++++++++++++++++\n";
  print "BUILD_DIST: $ENV{'BUILD_DIST'}\n";
  print "BUILD_MODE: $ENV{'BUILD_MODE'}\n";
  print "executing build command:\n";
  print "$build_cmd\n";

  my $do_log = open( LOG_FD, ">$logfilename" );
  if( $do_log ) {
    print "you can watch building with following command: \n";
    print "less +F $logfilename\n\n";
  } else {
  	print "could not open logfile $logfilename\n";
  }
  open( PIPE, "$build_cmd 2>&1 |" );
  while( <PIPE> ) {
  	if( ! $opt_x ) {
  	  print;
	}
	print LOG_FD if $do_log;
  }
  close PIPE; my $retval=$?>>8;
  close LOG_FD if $do_log;
  
  if ( $retval == 0 ) {
     $ArrayofBuilds[$i][3] = "OK";
     print"******                                                      ******\n";
     print"******   building of $ArrayofBuilds[$i][0]: OK                    \n" ;
     print"******                                                      ******\n";
  } elsif ( $retval == 1 ) {
  	$ArrayofBuilds[$i][3] = "skipped";
	$skipped_last = 1;
  } else {
     $ArrayofBuilds[$i][3] = "*FAILED*";
     print"******                                                      ******\n";
     print"\n\n\nERROR: building of $ArrayofBuilds[$i][0]: *FAILED*\n";
     print"******                                                      ******\n";
   }
}

print "Building results:\n";



($wert1,$wert2,$wert3)= ("BUILD_DIST","Result","Package");
$~="TABELLE";
write;

for my $i (0 .. $#ArrayofBuilds)
  {
    #($wert1,$wert2,$wert3)= ($ArrayofBuilds[$i][0],$ArrayofBuilds[$i][1],$ArrayofBuilds[$i][3]);
	($wert1,$wert2,$wert3) = ($ArrayofBuilds[$i][1],$ArrayofBuilds[$i][3],$ArrayofBuilds[$i][0]);
    $~="TABELLE";
    write;
	# print("$ArrayofBuilds[$i][0]:Result: $ArrayofBuilds[$i][3]");
  }

print "buildall.pl terminated\n";
}



#
# generating install source 
#

if( $opt_d ) {

	my $INSTALL_SRC_DEST_DIR=$opt_d;
	chomp $INSTALL_SRC_DEST_DIR;
	
	# create target directory
	run_command( "mkdir -p $INSTALL_SRC_DEST_DIR" );
	# copy skeletion to dest
	run_command( "rsync -av $INSTALL_SRC_SKEL_DIR $INSTALL_SRC_DEST_DIR" );
	
	# copy build packages to dest
	foreach my $i ( "i386", "i486", "i586", "i686", "noarch", "src" ) {
		run_command( "mkdir -p $INSTALL_SRC_DEST_DIR/suse/$i" );
		run_command( "rsync -av $BUILD_DEST_DIR/*/*.$i.rpm $INSTALL_SRC_DEST_DIR/suse/$i/" );
	}
	
	# create_package_descr (do that has to run on target distribution?)
	run_command( "cd $INSTALL_SRC_DEST_DIR/suse/; /usr/lib/YaST2/bin/create_package_descr -o $INSTALL_SRC_DEST_DIR/setup/descr" );
}


#
# functions
#

# executes a command (single string).
# returns 
# 	the returncode 
# 	and (combined) stdout and stderr

sub run_command
{
  my $command = shift;

  print "executing command: " . $command . "\n";

  open(RESULT, $command . ' 2>&1 |' );
  my @result = <RESULT>;
  close(RESULT);
  my $retcode = $?>>8;

  print @result;  
  if( $retcode ) { print "return code: " . $retcode . "\n"; }

  return($retcode, @result);
}
