#!/usr/bin/perl -w

# p4pkg.pl: wrapper to p4 to save old and new versions of files
# in a changelist, and package them up in a convenient tarball
# to be sent for review.
# If current file is out of sync with depot, it will diff against
# the version when it was opened, so old and new will contain
# only your changes, always.
# Usage: p4pkg.pl <changelist#>
# Author: Deepak Nagaraj <n.deepak@gmail.com>

use strict;

# debug?
my $DEBUG = 0;

# read changelist
defined $ARGV[0] || die "Usage: p4pkg.pl <changelist#>";
my $CHANGE = $ARGV[0];

# check if "p4" exists
system("p4 > /dev/null 2>&1") == 0 || die "can't find p4: $!";

# create subdir for changelist
system("mkdir -p $CHANGE") == 0 || die "can't mkdir $CHANGE: $!";

# read depot-to-client mapping
# first check if p4 where succeeds
system("p4 where > /dev/null") == 0 || 
	die "p4 where failed";
my $WHERE = `p4 where`;
my @MAPPING = split(/ /, $WHERE);

foreach (@MAPPING) {
	chomp;
	s/\.\.\.//g;	# remove the "..." in /foo/bar/...
	print $_ . "\n" if $DEBUG;
}

# read open files under that changelist
my $OPENED = `p4 opened -c $CHANGE`;
my @FILES = split(/\n/, $OPENED);

# change dir to $CHANGE and make new and old directories
chdir("$CHANGE") || die "can't chdir to $CHANGE: $!";
system("mkdir -p new") == 0 || die "can't mkdir $CHANGE/new: $!";
system("mkdir -p old") == 0 || die "can't mkdir $CHANGE/old: $!";

# for each open file
foreach (@FILES) {
	s/\s+.*//;						# strip everything after file#ver
	s/\#(.*)//;						# strip version
	my $VERSION = $1;				# but save it

	s/$MAPPING[0]/$MAPPING[2]/g;	# substitute depot ref with fs path
	print $_ . "\n" if $DEBUG;

	my $FILE = $_;
	my $FILENAME = substr($FILE, rindex($FILE, '/')+1);

	print "$FILENAME\n";

	# copy original file by printing depot version
	system("p4 print ${FILE}#${VERSION} > old/$FILENAME") == 0 || 
		die "p4 print failed";

	# copy changed file to <changelist>/<new> directory
	system("cp $FILE new/") == 0 || die "cp to subdir new failed: $!";
}

chdir("..");

# tar up <changelist> directory
system("tar -czf $CHANGE.tgz $CHANGE") == 0 || die "tar failed: $!";

exit 0;
