#!/usr/bin/perl # # genpatch - A utility that generates patches for submission to # wine-patches@winehq.com # # Copyright Steven Elliott # # 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.com =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/.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} : ""; 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 <) { chomp $cvs_line; if($cvs_line =~ /^\? (.*)/) { push @added_files, $1 unless(exists $options{a}); } else { print OPT_F ; } } 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 ; close DIFF_IN; } close OPT_F;