Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 1 | #!/usr/bin/perl |
| 2 | # |
| 3 | # genpatch - A utility that generates patches for submission to |
| 4 | # wine-patches@winehq.com |
| 5 | # |
| 6 | # By Steven Elliott <elliotsl@mindspring.com> |
| 7 | # |
| 8 | # This program is subject to the same license as Wine (www.winehq.com). |
| 9 | |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 10 | =head1 NAME |
| 11 | |
| 12 | genpatch - A utility that generates patches for submission to |
| 13 | wine-patches@winehq.com |
| 14 | |
| 15 | =head1 SYNOPSIS |
| 16 | |
| 17 | genpatch [B<-v>] [B<-n> patch_name] [B<-f> patch_file] |
| 18 | [B<-c> change_log] [B<-m> modified_files] |
| 19 | [B<-a> added_files] |
| 20 | |
| 21 | =head1 DESCRIPTION |
| 22 | |
| 23 | The genpatch utility generated patches for submission to |
| 24 | wine-patches@winehq by acting as a wrapper to "cvs diff". The "B<-v>" |
| 25 | switch specifies that verbose output should be generated. The "B<-n>" |
| 26 | switch overrides the patch name ("Name" field) which defaults to a |
| 27 | numeric UTC date. The "B<-f>" switch overrides the filename of the patch |
| 28 | which defaults to "patches/<patch_name>.diff". The "B<-c>" switch |
| 29 | specifies the CVS change log entry ("ChangeLog" field) which can be |
| 30 | seen when "cvs log" is invoked. The "B<-m>" ("ModifiedFiles" field) and |
| 31 | "B<-a>" ("AddedFiles" field) switches override the set of files that |
| 32 | would normally be included by the "cvs diff". Normally "cvs diff" |
| 33 | includes all files modified relative to the deltas indicated by the |
| 34 | "CVS/Entries" file and ignores all newly added files. The "B<-m>" switch |
| 35 | specifies a whitespace separated list of files that were modified. |
| 36 | The "B<-a>" switch specifies a whitespace separated list of files that |
| 37 | were added. |
| 38 | |
| 39 | =head1 EXAMPLE |
| 40 | |
| 41 | genpatch B<-n> NLSFix B<-c> "various fixes for NLS support" \ |
| 42 | B<-m> ole/ole2nls.c B<-a> ole/ole3nls.c |
| 43 | |
| 44 | The above generates a patch named "NLSFix" in "patches/NLSFix.diff" |
| 45 | that includes a modification to "ole/ole2nls.c" and a newly added |
| 46 | "ole/ole3nls.c". |
| 47 | |
| 48 | =cut |
| 49 | |
| 50 | use strict; |
| 51 | |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 52 | use Getopt::Std; |
| 53 | use File::Basename; |
| 54 | use POSIX qw(strftime); |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 55 | |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 56 | my $gen_date; # date the patch was generated |
| 57 | my %options; # command line options |
| 58 | my @modified_files; # optional list of files that were modified |
| 59 | my @added_files; # added files as an array |
| 60 | my $added_file; # added file being considered |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 61 | my $cvs_line; # line of output from CVS |
| 62 | my $mod_files_str; # string that describes the modified files |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 63 | |
| 64 | # Default the patch name to the UTC time. Use a more descriptive date for the |
| 65 | # patch generation date. |
| 66 | $options{n} = strftime "%Y%m%d%H%M", gmtime; |
| 67 | $gen_date = strftime "%Y/%m/%d %H:%M:%S UTC", gmtime; |
| 68 | |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 69 | unless(getopts("vn:f:c:m:a:p:", \%options)) |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 70 | { |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 71 | print STDERR "Usage: $0 [-v] [-n patch_name] [-f patch_file] " . |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 72 | "[-c change_log] [-m modified_files] [-a added_files] [-p path_to_patches]\n"; |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 73 | exit 1; |
| 74 | } |
| 75 | |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 76 | $options{p} = "patches" unless(exists $options{p}); |
| 77 | $options{f} = "$options{p}/$options{n}.diff" unless(exists $options{f}); |
| 78 | $options{p} = dirname $options{f}; |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 79 | @added_files = split ' ', $options{a}; |
| 80 | @modified_files = split ' ', $options{m}; |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 81 | $options{c} =~ s/\\n/\n\t/g; |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 82 | |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 83 | if(-d $options{p}) |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 84 | { |
| 85 | if(-e $options{f}) |
| 86 | { |
| 87 | print STDERR "$options{f} already exists. Aborting.\n"; |
| 88 | exit 1; |
| 89 | } |
| 90 | } |
| 91 | else |
| 92 | { |
Eric Pouech | e1885d1 | 2000-04-09 18:39:08 +0000 | [diff] [blame] | 93 | mkdir $options{p}, (0777 & ~umask) or |
| 94 | die "Unable to mkdir $options{p}: $!"; |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 95 | } |
| 96 | |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 97 | $mod_files_str = exists($options{m}) ? $options{m} : "<see cvs diff>"; |
| 98 | print "Generating $options{f}.\n" if($options{v}); |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 99 | open OPT_F, ">$options{f}" or die "Unable to open $options{f} for write: $!"; |
| 100 | print OPT_F <<EOF; |
| 101 | Name: $options{n} |
| 102 | ChangeLog: $options{c} |
| 103 | GenDate: $gen_date |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 104 | ModifiedFiles: $mod_files_str |
| 105 | AddedFiles: $options{a} |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 106 | EOF |
| 107 | |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 108 | print "Invoking cvs diff.\n" if($options{v}); |
| 109 | open CVS_IN, "cvs diff -u @modified_files|" or die "Unable to invoke cvs: $!"; |
| 110 | while($cvs_line = <CVS_IN>) |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 111 | { |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 112 | chomp $cvs_line; |
| 113 | if($cvs_line =~ /^\? (.*)/) |
| 114 | { |
| 115 | push @added_files, $1 unless(exists $options{a}); |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | print OPT_F <CVS_IN>; |
| 120 | } |
| 121 | } |
| 122 | close CVS_IN; |
| 123 | |
| 124 | foreach $added_file (@added_files) |
| 125 | { |
| 126 | print "Adding $added_file as a new file.\n" if($options{v}); |
| 127 | open DIFF_IN, "diff -u /dev/null $added_file|" or die "Unable to " . |
Steven Elliott | 32bfb62 | 2000-02-27 16:36:59 +0000 | [diff] [blame] | 128 | "invoke diff: $!"; |
| 129 | print OPT_F <DIFF_IN>; |
| 130 | close DIFF_IN; |
| 131 | } |
| 132 | |
Steven Elliott | a51c603 | 2000-03-19 12:46:02 +0000 | [diff] [blame] | 133 | close OPT_F; |