#!/usr/bin/perl

require 5.000;

use File::Copy qw( copy );
use File::Path qw( mkpath );
use File::Find qw( find );

# cvs2pack -- Sirtaj Singh Kang <taj@kde.org>, Dec 1998
# For the K Desktop Environment.

=head1 NAME

cvs2pack - Creates standalone dist tarballs for apps in KDE CVS.

=head1 SYNOPSIS

cvs2pack <module dir> <packagedir> [<version>]

=cut


($myname = $0) =~ s#.*/##g;
($basedir,$package) = @ARGV;
$version = undef;
$packagedir = "$package-$version";
@fromfiles = ();

@override	= ( "README", "INSTALL", "AUTHORS", "AUTHOR", "COPYING" );
@remove		= ( "config.cache", "config.log", "config.status", "Makefile", 
		"configure", "inst-apps" );
$copydir	= "pack";

# start

if ( $#ARGV < 0 ) {
	die <<EOF;

$myname -- Creates standalone tar.gz packages for apps in KDE CVS modules.

usage:
        $myname <module dir> <packagedir> [<version>]
        
example:
        $myname kdebase kioslave/smb 3.1 
        
This will create a package smb-3.1.tar.[gz|bz2] containing the sources 
from kdebase/kioslave/smb/ and the admin/ dir from kdebase/
        
EOF

}

main();

#end

sub main
{
# Figure out version

	if ( $#ARGV >= 2 ) {
		$version = $ARGV[ 2 ]
	}
	else {
		$version = getVersion();
	}

	if ( !defined $version ) {
		$version = "0.0"
	}

	print "$myname: Version: $version\n";

# dependent pathnames

        @subdirs = split(/\//,$package);
        $packagedir="@subdirs[$#subdirs]-$version";

	$origdir = $basedir."/".$package;

	mkpath ( $packagedir );
	push @fromfiles, "\"$origdir\"";
	
# base dir stuff
	push @fromfiles, basedirFiles();

# admin files
# Special case is when admin dir is a link, then link is not properly made
# This is now covered by using different options to cp
	push @fromfiles, "\"$basedir/admin\"";

# override files
	my $overp;
	my $over;
	
	foreach $over ( @override ) {
		$overp = $origdir."/".$over;
		
		if ( -f $overp ) {
			print "$myname: Overriding $over\n";
			push @fromfiles, '"'.$overp.'"' ;
		}
	}

# pack
	$packpath = $origdir."/".$copydir;
	if ( -d $packpath ) {
		push @fromfiles, $packpath."/*";
	}

# copy all queued files

	my $src = join( " ", @fromfiles );
	$src =~ s/\n/ /g;

	print "$myname: No. files in copy queue: ", $#fromfiles + 1,"\n";
	print $src ;
	print $packagedir;
	system "cp -pRL $src \"$packagedir\"";

# files to remove

	foreach $file ( @remove ) {
		unlink $packagedir."/".$file;
	}

	open (RM, "find \"$packagedir\" -name .deps -o -name .libs |" );

	my @rem = ();
	while ( <RM> ) {
		chop;
		print "$myname: removing $_\n";
		push @rem, $_;
	}

	system "rm -rf \"".join ( "\" \"", @rem )."\""
		unless $#rem < 0;
	
	close RM;

# rename crystal icons to hicolor icons as any good 3rdparty app

	open (RM, "find \"$packagedir\" -name \"hi[0-9][0-9]-*.png\" |" );

	while ( <RM> ) {
	  chop;
	  push hicolor, $_;
	}
	close RM;

	$hic = join( " ", @hicolor );

 # We only want to rename cr icons to hi in case the developer only
 # distributes icons in the cr icon theme.
	if ( not -z "$hic" ) {

	  open (RM, "find \"$packagedir\" -name \"cr[0-9][0-9]-*.png\" |" );

	  while ( <RM> ) {
	    chop;
	    $newname = $_ ;
	    $newname =~ s/cr([0-9][0-9])-([^\/]*$)/hi\1-\2/ ;
	    print "$myname: renaming $_ to $newname\n";
	    rename ( $_, $newname ) or die ( "Can't rename $_ to $newname: $!" );
	  }

	  close RM;
	}

# Creating a Makefile.am for the top dir

	ModifyMakefileAm( $package, $packagedir );

# Run Makefile.cvs
	print "$myname: Running Makefile.cvs...\n";
	system "cd \"$packagedir\" && make -f admin/Makefile.common dist".
		" && cd .. && tar cf \"$packagedir\".tar \"$packagedir\""
		|| die;

# Move Debian directory one level up if it exists
	if ( -d $packagedir."/".$package."/".debian ) {
		system "mv $packagedir/$package/debian $packagedir/debian";
	}

	print "Working dir:", `pwd`, "\n";
# Create tar.gz file

	print "tar cjf \"$packagedir.tar.bz2\" \"$packagedir\"\n";
	system "tar cjf \"$packagedir.tar.bz2\" \"$packagedir\"\n";
	print "tar czf \"$packagedir.tar.gz\" \"$packagedir\"\n";
	system "tar czf \"$packagedir.tar.gz\" \"$packagedir\"\n";

	print "Cleaning up after ourselves:\n";
	print "rm -rf \"$packagedir\"\n";
	system "rm -rf \"$packagedir\"\n"; 
}

sub basedirFiles
{
	my $files = `find '$basedir' -maxdepth 1 ! -type d`;
	chop $files;

	return '"'.join( '" "', split( /\n/, $files )).'"';
}

sub getVersion
{
	open ( CONFIN, $basedir."/configure.in" )
		|| die "Can't read $basedir/configure.in\n";

	while ( <CONFIN> ) {
		if( /AM_INIT_AUTOMAKE\((.*?),[ "]*(.*?)[ "]*\)/ ) {
			close( CONFIN );
			my $v = $2;
			$v =~ s/\s//g;
			
			return $v;
		}
	}

	close( CONFIN );
	return undef;
}

sub MakefileCVS
{
}

sub ModifyMakefileAm
{
	my ( $package, $packagedir ) = @_;

	my $old = "$packagedir/Makefile.am";
	my $new = "$packagedir/Makefile.am.new";
	my $bak = "$packagedir/Makefile.am.orig";

	open ( OLD, "< $old" ) or die ( "Can't open $old: $!" );
	open ( NEW, "> $new" ) or die ( "Can't open $new: $!" );

	# Correct SUBDIRS variable
	while (<OLD>) {
		s/SUBDIRS.*=.*\n/SUBDIRS=\$\(TOPSUBDIRS\)\n/i;
		(print NEW $_) or die "Can't write to $new: $!";
	}

	close ( OLD ) or die ( "Can't close $old: $!" );
	close ( NEW ) or die ( "Can't close $new: $!" );

	rename( $old, $bak ) or die ( "Can't rename $old to $bak: $!" );
	rename( $new, $old ) or die ( "Can't rename $new to $old: $!" );
}

=head1 DESCRIPTION

The following steps are performed:

=over 4

=item	Create a dist package dir and following files are copied:

=over 4

=item	the packagedir

=item	All non-dir files in the module dir

=item	the F<admin> dir

=back

=item	F<README>, F<INSTALL> and F<AUTHORS> are copied from package
	 	dir to the dist dir toplevel, if they exist.

=item	All files in <module dir>/<packagedir>/F<pack> are copied
		to the dist dir.

=item Makefile.cvs is run.

=item .tar.gz and .tar.bz2 archives are created for the directory.

=back

=head1 EXAMPLES

# cvs2pack ~/baseline/kdeutils karm 1.2

=head1 REQUIRED

Perl 5 is required. bzip2 is required for creation of .tar.bz2 files.

=head1 AUTHORS

Sirtaj Singh Kang <taj@kde.org>, Jan 1999.

=cut
