#!@-PERL-@ -w # -*- perl -*- # # This perl script is used to make a patch for your GnuCash # development work. All patches should be submitted to the # mailing list gnucash-devel@gnucash.org. For more info # consult README.patches # # WARNING: By default, this script will checkout an entire # up to date copy of the source tree in ../tmp/gnucash/. # # In order to prevent patches which reverse recent changes # made in CVS, make sure to "cvs update" in both # directories before running make-gnucash-patch. # # This script requires the programs 'makepatch', 'gzip', # a 'diff' work-a-like, and 'uuencode'. # # Author: Dave Peticolas use strict; use File::Basename; use Getopt::Long; $::ask_description = 1; $::should_uuencode = 1; $::diffcmd = "diff -up"; die "This utility has not been updated to use SVN. Sorry, just use diff(1)."; my $rcfile = $ENV{"HOME"} . "/.gnucash-patch.rc"; if (-f $rcfile) { require $rcfile; } ########################################################### # This section must be configured for your own setup. # ########################################################### # The directory with the original gnucash sources my $old = undef; chomp(my $cwd = `pwd`); my ($new, $gnc_home) = fileparse($cwd); ########################################################### # This section should not need to be modified. # ########################################################### # Allow the user to override the defaults with evnt vars. if($ENV{'GNC_MAKEPATCH_OLD_DIR'}) { $old = $ENV{'GNC_MAKEPATCH_OLD_DIR'}; } if($ENV{'GNC_MAKEPATCH_NEW_DIR'}) { $new = $ENV{'GNC_MAKEPATCH_NEW_DIR'}; } if($ENV{'GNC_MAKEPATCH_HOME_DIR'}) { $gnc_home = $ENV{'GNC_MAKEPATCH_HOME_DIR'}; } ########################################################### # Make sure makepatch exists before going on # ########################################################### open(OLDOUT, ">&STDOUT"); open(OLDERR, ">&STDERR"); open(STDOUT, "> /dev/null") || die "Can't redirect stdout"; open(STDERR, "> /dev/null") || die "Can't redirect stderr"; my $test = system('makepatch', "-help"); close(STDOUT); close(STDERR); open(STDOUT, ">&OLDOUT"); open(STDERR, ">&OLDERR"); close(OLDOUT); close(OLDERR); if($test == -1) { print "No makepatch installed. Exiting\n"; exit(10); } ########################################################### # Now, check if anything specified on command line # ########################################################### my $result; my $help; my $zip = 1; # defaults to on my $diffname = undef; my $ignorename = undef; my @filename = (); my $manifest = undef; $result = GetOptions("old=s" => \$old, "new=s" => \$new, "prefix=s" => \$gnc_home, "help" => \$help, "file=s" => \@filename, "ask!" => \$::ask_description, "diff=s" => \$diffname, "uuencode!" => \$::should_uuencode, "diffcmd!" => \$::diffcmd, "zip!" => \$zip, "ignore=s" => \$ignorename, "manifest=s" => \$manifest); if ($help or $result == 0) { printf "Help information\n\n"; printf "make-gnucash-patch accepts the following arguments:\n"; printf "--old \"olddir\" Directory of \"pristine\" copy\n"; printf "--new \"newdir\" Directory with modified copy\n"; printf "--prefex \"homedir\" Full path of parent directory\n"; printf "--diff \"diffname\" Output name for diff file\n"; printf "--diffcmd \"cmd\" Command to compare two files\n"; printf "--file \"filename\" Make patch for filename ONLY\n"; printf "--manifest \"file\" Use file as a manifest file\n"; printf "--ignore \"igname\" File containing file matches to ignore\n"; printf "--(no)uuencode Enable or disable uuencoded output\n"; printf " (Defaults to enabled)\n"; printf "--(no)zip Enable or disable gzipped output\n"; printf " (Defaults to enabled)\n"; printf "--(no)ask Enable or disable prompting for description\n"; printf " (Defaults to enabled)\n"; printf "and of course:\n"; printf "--help Displays this text\n"; printf "\nAll options can be abbreviated to their shortest unique\n"; printf " form: --o, --ne, --p, --d, --diffc, --f, --m, --i,\n"; printf " --u/--nou, --z/--noz, --a/--noa, and --h\n"; printf "\n"; exit 1; } # if explicit filename given, build required MANIFEST file @filename = split(/,/,join(',',@filename)); if (@filename) { open (FN, ">$gnc_home/tmp.MANIFEST") or die "Couldn't create MANIFEST file"; printf (FN "# Temporary manifest file for make-gnucash-patch -f option\n"); printf (FN "\n"); foreach my $part (@filename) { printf (FN "%s\n", $part); } close (FN); } # Switch to the home directory print "Changing directory to $gnc_home\n"; chdir $gnc_home or die "Can't cd!\n"; if (not defined($old)) { if (not -f "$new/CVS/Root") { print "Source not checked out of CVS and no \$old set. Quitting...\n"; exit(1); } if (not -d "tmp") { mkdir "tmp", 0755; } chdir "tmp"; system("cvs -d `cat ../$new/CVS/Root` co gnucash"); chdir ".."; $old = "tmp/gnucash"; } chdir $gnc_home . "/" . $new or die "Can't cd!\n"; # Start out with our basic makepatch arguments my @args = ('-verbose', '-exclude-vc'); # Push the diff command value push(@args, '-diff', "$::diffcmd"); if (not $::ask_description) { push(@args, '-description', ''); } # If -f options given, use generated manifest file # otherwise, add exclusions and proceed as normal if (@filename) { push(@args, '-manifest', "$gnc_home/tmp.MANIFEST"); } elsif (defined($manifest)) { if (not $manifest =~ m#/#) { $manifest = "$cwd/$manifest"; } push(@args, '-manifest', "$manifest"); } else { # Add in the exclude patterns from the __DATA__ section push_exclusions(\@args); } sub push_exclusions { my $args = shift; foreach my $pat () { chomp($pat); push(@{$args}, '-exclude', $pat) if $pat; } if (defined ($ignorename)) { $ignorename = "../" . $ignorename; if (-e $ignorename) { open (IG, $ignorename) or die "Couldn't open $ignorename"; foreach my $igf () { chomp ($igf); push(@{$args}, '-exclude', $igf) if $igf; } close (IG); } } my @cvsignores = `find . -name '.cvsignore'`; foreach my $one_ignore (@cvsignores) { my ($name, $path) = fileparse($one_ignore); open (IG, $one_ignore); foreach my $fl () { chomp $fl; $path =~ s/^\.\///; push(@{$args}, '-exclude', $path . $fl) if $fl; } close (IG); } } # Add the from and to directories for makepatch push(@args, $old, $new); print "Arguments are: " . join("; ", @args) . "\n"; chdir $gnc_home or die "Can't cd!\n"; # Erase the old files #unlink('gnc.diff', 'gnucash.diff.gz', 'gnucash.diff.gz.uue'); if (not -d "diffs") { mkdir "diffs", 0755; } my $outfilename; if (not defined($diffname)) { my $date = `date '+%Y%m%d-%H%M%S'`; chomp($date); my $who = `whoami`; chomp($who); $outfilename = "gnucash-$date-$who.diff"; } else { $outfilename = $diffname; } # Invoke makepatch with standard out redirected to 'gnucash.diff' open(OLDOUT, ">&STDOUT"); open(STDOUT, "> diffs/$outfilename") || die "Can't redirect stdout"; system('makepatch', @args); close(STDOUT); open(STDOUT, ">&OLDOUT"); close(OLDOUT); print "makepatch done\n"; # Compress the patch if required if ($zip) { if (-f "diffs/$outfilename") { system("gzip", "-9vf", "diffs/$outfilename"); } } # UU encode the patch if required # if $zip is true, then # 'gnucash.diff.gz.uue' is the file you send. if ($zip and -f "diffs/$outfilename.gz" and $::should_uuencode) { system("uuencode diffs/$outfilename.gz $outfilename.gz > diffs/$outfilename.gz.uue"); print "diffs/$outfilename.gz.uue\n"; } else { if (not $zip and -f "diffs/$outfilename" and $::should_uuencode) { system("uuencode diffs/$outfilename $outfilename > diffs/$outfilename.uue"); print "diffs/$outfilename.uue\n"; } } exit(0); __DATA__ #*# *.P *.pp *.a *.bak *.bin *.diff *.diffs *.gmo *.la *.lai *.lo *.loT *.log *.mo *.moc *.o *.orig *.ignmgp *.patch *.rej *.tar.gz *.wrap *.xac.*.xac *~ .#* doc/gnc-prices.1 doc/gnucash.1