#!perl
# $Id: makerelease.pl,v 1.9 2004/09/30 07:34:13 jlinoff Exp $
#
# Generate the ccdoc release from the local bin_opt_ directories.
#
use strict;

&Main;

# ================================================
# Main
# ================================================
sub Main
{
    # ================================================
    # Read the release.txt file contents.
    # ================================================
    my $file = "../src/release.txt";
    if( ! -e $file ) {
	print STDERR "ERROR: Can't read release.txt.\n";
	exit 1;
    }
    my $rev = "";
    my $date = "";
    open HND,"$file" || die "ERROR: Can't read '$file'.\n";
    while( <HND> ) {
	chop;
	next if ( /^\s*\#/ );
	if( /(\S+)\s+(\S+)/ ) {
	    $rev = $1;
	    $date = $2;
	    last;
	}
    }
    close HND;
    if( $rev eq "" || $date eq "" ) {
	print STDERR "ERROR: Invalid syntax in release.txt,\n";
	print STDERR "       Expected: <rev> <date>\n";
	exit 1;
    }
    my $relname = "ccdoc${rev}";
    print "Releasing $relname ...\n";

    # ================================
    # Figure out the release executables by looking
    # at the bin_opt directories.
    # ================================
    opendir DIR,"../";
    my @bin_opt_dirs = grep { /^bin_opt_/ && -d "../$_" } readdir(DIR);
    closedir DIR;

    # ================================
    # Fix DOS CR stuff.
    # ================================
    system("perl ../utils/pc2unix.pl *.cc *.h *.html *.txt Makefile *.mk");
    system("perl ../utils/pc2unix.pl ../utils/*.pl");
    system("perl ../utils/pc2unix.pl ../test/*.h");

    # ================================
    # Clean up the release area.
    # ================================
    if( -d "../$relname" ) {
	system("rm -rf ../$relname");
	if( -d "../$relname" ) {
	    print STDERR "WARNING: Delete of ../$relname failed.\n";
	}
    }
    mkdir "../$relname";
    mkdir "../$relname/release";
    mkdir "../$relname/release/downloads";
    mkdir "../$relname/release/downloads/utils";

    # ================================
    # Create the summary file.
    # ================================
    my $sum = "../$relname/release.txt";
    open SUM,">$sum" || die "ERROR: Can't write file '$sum'.\n";
    print SUM "RELEASE: $relname\n";

    # ================================
    # Copy over the binary executables.
    # Create gzip and zip versions.
    # ================================
    my $bin_opt_dir;
    foreach $bin_opt_dir ( @bin_opt_dirs ) {
	my $exe_file = "../$bin_opt_dir/ccdoc.exe";
	print "$exe_file\n";
	if( !-e $exe_file ) {
	    print STDERR "WARNING: File '$exe_file' does not exist.\n";
	}
	if( -e $exe_file ) {
	    my $dstdir = "../$relname/release/downloads/$bin_opt_dir";
	    print "Creating $dstdir/ccdoc.exe\n";
	    system("mkdir -p $dstdir");
	    print "$bin_opt_dir\n";
	    print SUM "$bin_opt_dir\n";
	    system("cp $exe_file $dstdir");
	    PrintFileInfo(\*SUM,"  ",24,14,"$dstdir","ccdoc.exe");
	    system("gzip --best -c $exe_file > $dstdir/ccdoc.exe.gz");
	    PrintFileInfo(\*SUM,"  ",24,14,"$dstdir","ccdoc.exe.gz");
	    system("zip -q -j $dstdir/ccdoc.exe.zip $exe_file");
	    PrintFileInfo(\*SUM,"  ",24,14,"$dstdir","ccdoc.exe.zip");
	}
    }

    # ================================
    # Copy over the interesting
    # directory trees.
    # ================================
    my $backup = $relname;
    &CopyDirTree("../doc","../$relname/${backup}/doc");
    &CopyDirTree("../doc","../$relname/release");
    &CopyDirTree("../src","../$relname/${backup}/src");
    &CopyDirTree("../test","../$relname/${backup}/test");
    &CopyDirTree("../utils","../$relname/${backup}/utils");

    # ================================
    # Copy over the interesting
    # utilities.
    # ================================
    my $dstdir = "../$relname/release/downloads/utils";
    system("cp ../utils/counter.pl $dstdir");
    system("cp ../utils/dtree.pl $dstdir");
    system("cp ../doc/htdocs/issues/make_issues.pl $dstdir");

    # ================================
    # Create and copy the man page
    # to three places:
    # 1) the doc directory so that
    #    it shows up in the doc tarball.
    # 2) the release downloads directory
    #    to that it will be found by the
    #    downloads page.
    # 3) the release/doc directory so
    #    that it matches the doc tarball.
    # ================================
    my $makeman = "../utils/makeman.pl";
    my $manpage = "../$relname/$relname/doc/htdocs/ccdoc.man";
    my $help = "../src/help.txt";
    my $license = "../src/copyright.tx";
    system("perl $makeman -h $help -l $license -o $manpage");
    system("perl ../utils/pc2unix.pl $manpage");
    $manpage = "../$relname/release/downloads/ccdoc.man";
    system("perl $makeman -h $help -l $license -o $manpage");
    system("perl ../utils/pc2unix.pl $manpage");
    $manpage = "../$relname/release/htdocs/ccdoc.man";
    system("perl $makeman -h $help -l $license -o $manpage");
    system("perl ../utils/pc2unix.pl ../$relname/$relname//ccdoc.man");

    print "man_page\n";
    print SUM "man_page\n";
    PrintFileInfo(\*SUM,"  ",24,14,"../$relname/release/downloads","ccdoc.man");

    # ================================
    # Tarballs
    # ================================
    print "tarballs\n";
    print SUM "tarballs\n";

    # ================================
    # Create the src tarball.
    # ================================
    my $tarball = "src";
    chdir "../$relname";
    system("tar cf ${tarball}.tar ${backup}");
    system("gzip --best -c ${tarball}.tar > ${tarball}.tar.gz");
    unlink("${tarball}.tar");
    system("mv ${tarball}.tar.gz release/downloads");
    chdir "../src";
    PrintFileInfo(\*SUM,"  ",24,14,"../$relname/release/downloads","${tarball}.tar.gz");

    # ================================
    # Create the doc tarball.
    # ================================
    $tarball = "doc";
    chdir "../$relname";
    system("tar cf ${tarball}.tar ${backup}/doc");
    system("gzip --best -c ${tarball}.tar > ${tarball}.tar.gz");
    unlink("${tarball}.tar");
    system("mv ${tarball}.tar.gz release/downloads");
    chdir "../src";
    PrintFileInfo(\*SUM,"  ",24,14,"../$relname/release/downloads","${tarball}.tar.gz");

    # ================================
    # Create the release tarball.
    # ================================
    $tarball = "release";
    chdir "../$relname/release";
    system("tar cf ../${tarball}.tar .");
    chdir "..";
    system("gzip --best -c ${tarball}.tar > ${tarball}.tar.gz");
    unlink("${tarball}.tar");
    PrintFileInfo(\*SUM,"  ",24,14,".","${tarball}.tar.gz");

    close SUM;

    # ================================
    # Update the downloads page.
    # ================================
    system("perl ../utils/update_downloads_page.pl");
}
# ================================================
# Copy directory tree and remove the CVS stuff.
# ================================================
sub CopyDirTree
{
    my $src = shift;
    my $dst = shift;
    system("mkdir -p $dst");
    system("cp -r $src/* $dst/");
    system("rm -rf $dst/CVS $dst/*/CVS $dst/*/*/CVS $dst/*/*/*/CVS");
}
# ================================================
# Print file info.
# ================================================
sub PrintFileInfo
{
    my $out = shift;
    my $p = shift;
    my $n1 = shift;
    my $n2 = shift;
    my $path = shift;
    my $file = shift;

    my @info = stat("$path/$file");
    my $sz = $info[7];
    my $kb = sprintf "%d",$sz/1024;
    my $fmt = "$p%-${n1}s %${n2}s %${n2}s Kb\n";
    printf $fmt, $file, &FmtNum($sz), &FmtNum($kb);
    printf $out $fmt, $file, &FmtNum($sz), &FmtNum($kb);
}	    
# ================================================
# Format number.
# ================================================
sub FmtNum
{
    my $num = shift;
    my $fmt = $num;
    my $frac = "";
    if( $num =~ /\./ ) {
	$frac = $num;
	$frac =~ s/[0-9]*\.//;
    }
    $fmt =~ s/\..*$//;
    $fmt =~ s/(.........)$/,\1/ if( length($fmt) > 9 );
    $fmt =~ s/(......)$/,\1/ if( length($fmt) > 6 );
    $fmt =~ s/(...)$/,\1/ if( length($fmt) > 3 );
    if( $frac > 0 ) {
	if( $frac >= 1000 ) {
	    $frac =~ s/^(...).*$/\1/;
	}
	$fmt = "${fmt}.${frac}";
    }
    return $fmt;
}
	    

