#!/usr/bin/perl
#
# genpatch - A utility that generates patches for submission to
# wine-patches@winehq.org
#
# Copyright Steven Elliott <elliotsl@mindspring.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

=head1 NAME

genpatch - A utility that generates patches for submission to
wine-patches@winehq.org

=head1 SYNOPSIS

genpatch [B<-v>] [B<-n> patch_name] [B<-f> patch_file]
         [B<-c> change_log] [B<-m> modified_files]
         [B<-a> added_files]

=head1 DESCRIPTION

The genpatch utility generated patches for submission to
wine-patches@winehq by acting as a wrapper to "cvs diff".  The "B<-v>"
switch specifies that verbose output should be generated.  The "B<-n>"
switch overrides the patch name ("Name" field) which defaults to a
numeric UTC date.  The "B<-f>" switch overrides the filename of the patch
which defaults to "patches/<patch_name>.diff".  The "B<-c>" switch
specifies the CVS change log entry ("ChangeLog" field) which can be
seen when "cvs log" is invoked.  The "B<-m>" ("ModifiedFiles" field) and
"B<-a>" ("AddedFiles" field) switches override the set of files that
would normally be included by the "cvs diff".  Normally "cvs diff"
includes all files modified relative to the deltas indicated by the
"CVS/Entries" file and ignores all newly added files.  The "B<-m>" switch
specifies a whitespace separated list of files that were modified.
The "B<-a>" switch specifies a whitespace separated list of files that
were added.

=head1 EXAMPLE

genpatch B<-n> NLSFix B<-c> "various fixes for NLS support" \
    B<-m> ole/ole2nls.c B<-a> ole/ole3nls.c

The above generates a patch named "NLSFix" in "patches/NLSFix.diff"
that includes a modification to "ole/ole2nls.c" and a newly added
"ole/ole3nls.c".

=cut

use strict;

use Getopt::Std;
use File::Basename;
use POSIX qw(strftime);

my $gen_date;       # date the patch was generated
my %options;        # command line options
my @modified_files; # optional list of files that were modified
my @added_files;    # added files as an array
my $added_file;     # added file being considered
my $cvs_line;       # line of output from CVS
my $mod_files_str;  # string that describes the modified files

# Default the patch name to the UTC time.  Use a more descriptive date for the
# patch generation date.
$options{n} = strftime "%Y%m%d%H%M", gmtime;
$gen_date = strftime "%Y/%m/%d %H:%M:%S UTC", gmtime;

unless(getopts("vn:f:c:m:a:p:", \%options))
{
    print STDERR "Usage: $0 [-v] [-n patch_name] [-f patch_file] " .
        "[-c change_log] [-m modified_files] [-a added_files] [-p path_to_patches]\n";
    exit 1;
}

$options{p} = "patches" unless(exists $options{p});
$options{f} = "$options{p}/$options{n}.diff" unless(exists $options{f});
$options{p} = dirname $options{f};
@added_files = split ' ', $options{a};
@modified_files = split ' ', $options{m};
$options{c} =~ s/\\n/\n\t/g;

if(-d $options{p})
{
    if(-e $options{f})
    {
        print STDERR "$options{f} already exists.  Aborting.\n";
        exit 1;
    }
}
else
{
    mkdir $options{p}, (0777 & ~umask) or
        die "Unable to mkdir $options{p}: $!";
}

$mod_files_str = exists($options{m}) ? $options{m} : "<see cvs diff>";
print "Generating $options{f}.\n" if($options{v});
open OPT_F, ">$options{f}" or die "Unable to open $options{f} for write: $!";
print OPT_F <<EOF;
Name: $options{n}
ChangeLog: $options{c}
GenDate: $gen_date
ModifiedFiles: $mod_files_str
AddedFiles: $options{a}
EOF

print "Invoking cvs diff.\n" if($options{v});
open CVS_IN, "cvs diff -u @modified_files|" or die "Unable to invoke cvs: $!";
while($cvs_line = <CVS_IN>)
{
    chomp $cvs_line;
    if($cvs_line =~ /^\? (.*)/)
    {
        push @added_files, $1 unless(exists $options{a});
    }
    else
    {
        print OPT_F <CVS_IN>;
    }
}
close CVS_IN;

foreach $added_file (@added_files)
{
    print "Adding $added_file as a new file.\n" if($options{v});
    open DIFF_IN, "diff -u /dev/null $added_file|" or die "Unable to " .
        "invoke diff: $!";
    print OPT_F <DIFF_IN>;
    close DIFF_IN;
}

close OPT_F;
