#!/usr/bin/perl
# Update PTAR
#
# This script will generate a new pristine-tar metafile that
# can be used to recreate the original tarball (with the same
# MD5 signature).
#
# Usage:
#   --help          Print out a usage message
#   --verbose       Print out extra progress and status messages
#

use strict;
use warnings;

use File::Path   ();
use Getopt::Long ();

my $opt_help;
my $opt_verbose;
my $result = Getopt::Long::GetOptions(
    'help'    => \$opt_help,
    'verbose' => \$opt_verbose,
);

if ($opt_help) {
    print_usage();
    exit;
}

if ( !@ARGV ) {
    print "You must specify a tarball to unpack.\n";
    print_usage();
    exit 1;
}

for my $tgz (@ARGV) {
    process_tgz($tgz);
}

sub process_tgz {
    my ($name) = @_;

    $name =~ s{/+$}{};    # Trim trailing slashes
    my $tgz_name;
    my $source_dir;
    my $ptar_name;

    if ( $name =~ /\.d$/ ) {
        $source_dir = $name;
        ( $tgz_name  = $name ) =~ s{\.d$}{};
        ( $ptar_name = $name ) =~ s{\.d$}{.ptar};
    }
    elsif ( $name =~ /\.ptar$/ ) {
        $ptar_name = $name;
        ( $tgz_name   = $name ) =~ s{\.ptar$}{};
        ( $source_dir = $name ) =~ s{\.ptar$}{.d};
    }
    else {
        $tgz_name   = $name;
        $source_dir = $name . '.d';
        $ptar_name  = $name . '.ptar';
    }

    if ( $tgz_name !~ /\.pm(?:\.patch)?\.tar\.gz/ ) {
        die "$tgz_name does not appear to be a valid tarball name\n";
    }

    if ( !-d $source_dir ) {
        die "Directory $source_dir does not exist or is not a directory\n";
    }

    print "Processing $tgz_name...\n";

    if ( -e $tgz_name ) {
        print "Removing the existing tarball file $tgz_name ...\n" if $opt_verbose;
        unlink $tgz_name
          or die "Tarball file $tgz_name exists and cannot be removed\n";
    }

    if ( -e $ptar_name ) {
        print "Removing the existing pristine-tar metadata file $ptar_name ...\n" if $opt_verbose;
        unlink $ptar_name
          or die "Pristine-tar file $ptar_name exists and cannot be removed\n";
    }

    # Get the list of top-level files/directories to be included in the tarball
    opendir my $dh, $source_dir
      or die "Failed to open directory $source_dir: $!";
    my @files = grep { $_ !~ /^\.\.?/ } ( readdir $dh );
    closedir $dh
      or die "Failed to close directory $source_dir: $!";

    print "Creating the tarball file $tgz_name ...\n" if $opt_verbose;
    system( 'tar', 'czvf', $tgz_name, '-C', $source_dir, @files ) == 0
      or die "Failed to create tarball";

    print "Creating the pristine-tar metadata file $ptar_name ...\n" if $opt_verbose;
    system( 'pristine-tar', 'gendelta', $tgz_name, $ptar_name ) == 0
      or die "Failed to create pristine-tar file";

    print "Cleaning up the tarball file $tgz_name ...\n" if $opt_verbose;
    unlink $tgz_name
      or die "Tarball file $tgz_name cannot be removed\n";
}

sub print_usage {
    print <<"USAGE";

$0 [ --help ] [ --verbose ]
    --help          Print out a usage message
    --verbose       Print progress messages during processing

USAGE
}
