#!/usr/bin/perl -w
# $Id: compare-manifests,v 1.3 2016/07/03 18:35:12 tom Exp $
# -----------------------------------------------------------------------------
# Copyright 2016 by Thomas E. Dickey
#
#                         All Rights Reserved
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name(s) of the above copyright
# holders shall not be used in advertising or otherwise to promote the
# sale, use or other dealings in this Software without prior written
# authorization.
# -----------------------------------------------------------------------------
# For a given project, use "release2git -R" to find its labeled releases, and
# generate a manifest-file for each of these.  Discount the first line, and
# compare successive files to identify changes from one release to the next.

use strict;

use File::Path qw(make_path remove_tree);
use File::Temp qw/ tempdir /;
use Getopt::Std;

$| = 1;

our ( $opt_d, $opt_v );

sub compare_manifests($) {
    my $project = shift;
    printf "** %s\n", $project;
    our $working  = tempdir( CLEANUP => 1 );
    our $rcs_tree = tempdir( CLEANUP => 1 );
    if ( open my $fh, "release2git -R -d$working $project |" ) {
        my @report = <$fh>;
        close $fh;

        my $previous = "";
        for my $n ( 0 .. $#report ) {
            chomp $report[$n];
            our @fields = split /\s+/, $report[$n];
            next unless ( $#fields >= 2 );

            my $verbose = $opt_v ? "-v" : "";
            my $timestamp = sprintf "%s %s", $fields[0], $fields[1];
            for my $r ( 2 .. $#fields ) {
                my $release = $fields[$r];
                $release =~ s/,//;
                my $manifest = "$working/MANIFEST";

                unlink "$manifest";
                system( "release2git "
                      . "$verbose " . "-p "
                      . "-r$release "
                      . "-d$working "
                      . "-t$rcs_tree "
                      . "$project" );
                if ( -f $manifest ) {
                    system("touch -d '$timestamp' $manifest");
                    system("mv $verbose -f $manifest $opt_d/$release");
                }
                if ( $previous ne "" ) {
                    system("cd $opt_d; diff -u $previous $release");
                }
                $previous = $release;
            }
        }
    }
    else {
        die "cannot find project $project: $!";
    }
}

sub main::HELP_MESSAGE() {
    printf STDERR <<EOF
Usage: $0 [options]

Options:

  -d dir     use this staging directory (otherwise temporary)
  -v         verbose (shows files created)
EOF
      ;
    exit;
}

&getopts('d:v') || main::HELP_MESSAGE;

&make_path($opt_d) if ($opt_d);
$opt_d = tempdir( CLEANUP => 1 ) unless ($opt_d);
&remove_tree( $opt_d, { keep_root => 1 } );

if ( $#ARGV >= 0 ) {
    while ( $#ARGV >= 0 ) {
        &compare_manifests( shift @ARGV );
    }
}
else {
    &compare_manifests(".");
}

1;
